@ -88,7 +88,7 @@ type buildOptions struct {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					control . ControlOptions 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  ( o  * buildOptions )  toControllerOptions ( )  ( controllerapi . BuildOptions ,  error )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  ( o  * buildOptions )  toControllerOptions ( )  ( * controllerapi . BuildOptions ,  error )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  err  error 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts  :=  controllerapi . BuildOptions { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						Allow :           o . allow , 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -130,43 +130,43 @@ func (o *buildOptions) toControllerOptions() (controllerapi.BuildOptions, error)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . Attests ,  err  =  buildflags . ParseAttests ( inAttests ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . NamedContexts ,  err  =  buildflags . ParseContextNames ( o . contexts ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . Exports ,  err  =  buildflags . ParseExports ( o . outputs ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					for  _ ,  e  :=  range  opts . Exports  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  ( e . Type  ==  client . ExporterLocal  ||  e . Type  ==  client . ExporterTar )  &&  o . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  controllerapi . BuildOptions { } ,  errors . Errorf ( "local and tar exporters are incompatible with image ID file" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil ,  errors . Errorf ( "local and tar exporters are incompatible with image ID file" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . CacheFrom ,  err  =  buildflags . ParseCacheEntry ( o . cacheFrom ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . CacheTo ,  err  =  buildflags . ParseCacheEntry ( o . cacheTo ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . Secrets ,  err  =  buildflags . ParseSecretSpecs ( o . secrets ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts . SSH ,  err  =  buildflags . ParseSSHSpecs ( o . ssh ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  controllerapi . BuildOptions { } ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  opts ,  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  & opts ,  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  ( o  * buildOptions )  toProgress ( )  ( string ,  error )  { 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -185,9 +185,8 @@ func (o *buildOptions) toProgress() (string, error) {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  o . progress ,  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  runBuild ( dockerCli  command . Cli ,   in buildOptions )  error  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  runBuild ( dockerCli  command . Cli ,  opt io ns  buildOptions )  ( err  error )   { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					ctx  :=  appcontext . Context ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					ctx ,  end ,  err  :=  tracing . TraceCurrentCommand ( ctx ,  "build" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -196,36 +195,144 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						end ( err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts ,  err  :=  in . toControllerOptions ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					progress ,  err  :=  in . toProgress ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Avoid leaving a stale file if we eventually fail
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if   in. imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  os . Remove (  in. imageIDFile ) ;  err  !=  nil  &&  ! os . IsNotExist ( err )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  os . Remove ( options . imageIDFile ) ;  err  !=  nil  &&  ! os . IsNotExist ( err )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  errors . Wrap ( err ,  "removing image ID file" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					resp ,  _ ,  err  :=  cbuild . RunBuild ( ctx ,  dockerCli ,  opts ,  os . Stdin ,  progress ,  nil ,  false ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					progressMode ,  err  :=  options . toProgress ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  in . quiet  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  resp  * client . SolveResponse 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  retErr  error 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  isExperimental ( )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						resp ,  retErr  =  runControllerBuild ( ctx ,  dockerCli ,  options ,  progressMode ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					}  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						resp ,  retErr  =  runBasicBuild ( ctx ,  dockerCli ,  options ,  progressMode ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  retErr  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  retErr 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . quiet  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						fmt . Println ( resp . ExporterResponse [ exptypes . ExporterImageDigestKey ] ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  in . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  opt io ns . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						dgst  :=  resp . ExporterResponse [ exptypes . ExporterImageDigestKey ] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  v ,  ok  :=  resp . ExporterResponse [ exptypes . ExporterImageConfigDigestKey ] ;  ok  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							dgst  =  v 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  os . WriteFile ( in . imageIDFile ,  [ ] byte ( dgst ) ,  0644 ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  os . WriteFile ( options . imageIDFile ,  [ ] byte ( dgst ) ,  0644 ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  runBasicBuild ( ctx  context . Context ,  dockerCli  command . Cli ,  options  buildOptions ,  progressMode  string )  ( * client . SolveResponse ,  error )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts ,  err  :=  options . toControllerOptions ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					resp ,  _ ,  err  :=  cbuild . RunBuild ( ctx ,  dockerCli ,  * opts ,  os . Stdin ,  progressMode ,  nil ,  false ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  resp ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  runControllerBuild ( ctx  context . Context ,  dockerCli  command . Cli ,  options  buildOptions ,  progressMode  string )  ( * client . SolveResponse ,  error )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . invoke  !=  nil  &&  ( options . dockerfileName  ==  "-"  ||  options . contextPath  ==  "-" )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						// stdin must be usable for monitor
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  errors . Errorf ( "Dockerfile or context from stdin is not supported with invoke" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					c ,  err  :=  controller . NewController ( ctx ,  options . ControlOptions ,  dockerCli ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					defer  func ( )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  c . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "failed to close server connection %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Start build
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts ,  err  :=  options . toControllerOptions ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// NOTE: buildx server has the current working directory different from the client
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// so we need to resolve paths to abosolute ones in the client.
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts ,  err  =  resolvePaths ( opts ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  nil ,  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  ref  string 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  retErr  error 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  resp  * client . SolveResponse 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					f  :=  ioset . NewSingleForwarder ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					f . SetReader ( os . Stdin ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ! options . noBuild  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						pr ,  pw  :=  io . Pipe ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						f . SetWriter ( pw ,  func ( )  io . WriteCloser  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							pw . Close ( )  // propagate EOF
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "propagating stdin close" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						ref ,  resp ,  err  =  c . Build ( ctx ,  * opts ,  pr ,  os . Stdout ,  os . Stderr ,  progressMode ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							var  be  * controllererrors . BuildError 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  errors . As ( err ,  & be )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								ref  =  be . Ref 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								retErr  =  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								// We can proceed to monitor
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							}  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								return  nil ,  errors . Wrapf ( err ,  "failed to build" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pw . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close stdin pipe writer" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pr . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close stdin pipe reader" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// post-build operations
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . invoke  !=  nil  &&  options . invoke . needsMonitor ( retErr )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						pr2 ,  pw2  :=  io . Pipe ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						f . SetWriter ( pw2 ,  func ( )  io . WriteCloser  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							pw2 . Close ( )  // propagate EOF
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						con  :=  console . Current ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  con . SetRaw ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  err  :=  c . Disconnect ( ctx ,  ref ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								logrus . Warnf ( "disconnect error: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil ,  errors . Errorf ( "failed to configure terminal: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						err  =  monitor . RunMonitor ( ctx ,  ref ,  opts ,  options . invoke . InvokeConfig ,  c ,  progressMode ,  pr2 ,  os . Stdout ,  os . Stderr ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						con . Reset ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pw2 . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close monitor stdin pipe reader" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "failed to run monitor: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					}  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  c . Disconnect ( ctx ,  ref ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "disconnect error: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  resp ,  retErr 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  buildCmd ( dockerCli  command . Cli ,  rootOpts  * rootOptions )  * cobra . Command  { 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -252,17 +359,15 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							options . progress  =  cFlags . progress 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							cmd . Flags ( ) . VisitAll ( checkWarnedFlags ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  isExperimental ( )  {  
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  invokeFlag  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									 invoke Config ,  err  :=  parseInvokeConfig ( invokeFlag ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								invoke ,  err  :=  parseInvokeConfig ( invokeFlag ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									 options . invoke  =  & invoke Config 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								options . invoke  =  & invoke 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								options . noBuild  =  invokeFlag  ==  "debug-shell" 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								return  launchControllerAndRunBuild ( dockerCli ,  options ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  runBuild ( dockerCli ,  options ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -494,123 +599,6 @@ func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  txn . UpdateLastActivity ( ng ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				func  launchControllerAndRunBuild ( dockerCli  command . Cli ,  options  buildOptions )  error  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					ctx  :=  context . TODO ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . invoke  !=  nil  &&  ( options . dockerfileName  ==  "-"  ||  options . contextPath  ==  "-" )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						// stdin must be usable for monitor
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  errors . Errorf ( "Dockerfile or context from stdin is not supported with invoke" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					c ,  err  :=  controller . NewController ( ctx ,  options . ControlOptions ,  dockerCli ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					defer  func ( )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  c . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "failed to close server connection %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Start build
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts ,  err  :=  options . toControllerOptions ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					progress ,  err  :=  options . toProgress ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// NOTE: buildx server has the current working directory different from the client
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// so we need to resolve paths to abosolute ones in the client.
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					optsP ,  err  :=  resolvePaths ( & opts ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					opts  =  * optsP 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  ref  string 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					var  retErr  error 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					f  :=  ioset . NewSingleForwarder ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					f . SetReader ( os . Stdin ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ! options . noBuild  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						pr ,  pw  :=  io . Pipe ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						f . SetWriter ( pw ,  func ( )  io . WriteCloser  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							pw . Close ( )  // propagate EOF
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "propagating stdin close" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						// Avoid leaving a stale file if we eventually fail
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  options . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  err  :=  os . Remove ( options . imageIDFile ) ;  err  !=  nil  &&  ! os . IsNotExist ( err )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								return  errors . Wrap ( err ,  "removing image ID file" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						var  resp  * client . SolveResponse 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						ref ,  resp ,  err  =  c . Build ( ctx ,  opts ,  pr ,  os . Stdout ,  os . Stderr ,  progress ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							var  be  * controllererrors . BuildError 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  errors . As ( err ,  & be )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								ref  =  be . Ref 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								retErr  =  err 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								// We can proceed to monitor
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							}  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								return  errors . Wrapf ( err ,  "failed to build" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pw . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close stdin pipe writer" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pr . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close stdin pipe reader" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  options . quiet  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							fmt . Println ( resp . ExporterResponse [ exptypes . ExporterImageDigestKey ] ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  options . imageIDFile  !=  ""  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							dgst  :=  resp . ExporterResponse [ exptypes . ExporterImageDigestKey ] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  v ,  ok  :=  resp . ExporterResponse [ exptypes . ExporterImageConfigDigestKey ] ;  ok  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								dgst  =  v 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  os . WriteFile ( options . imageIDFile ,  [ ] byte ( dgst ) ,  0644 ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// post-build operations
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  options . invoke  !=  nil  &&  options . invoke . needsMonitor ( retErr )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						pr2 ,  pw2  :=  io . Pipe ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						f . SetWriter ( pw2 ,  func ( )  io . WriteCloser  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							pw2 . Close ( )  // propagate EOF
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						con  :=  console . Current ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  con . SetRaw ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  err  :=  c . Disconnect ( ctx ,  ref ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								logrus . Warnf ( "disconnect error: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  errors . Errorf ( "failed to configure terminal: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						err  =  monitor . RunMonitor ( ctx ,  ref ,  & opts ,  options . invoke . InvokeConfig ,  c ,  progress ,  pr2 ,  os . Stdout ,  os . Stderr ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						con . Reset ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  pw2 . Close ( ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Debug ( "failed to close monitor stdin pipe reader" ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "failed to run monitor: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					}  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  err  :=  c . Disconnect ( ctx ,  ref ) ;  err  !=  nil  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							logrus . Warnf ( "disconnect error: %v" ,  err ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				type  invokeConfig  struct  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					controllerapi . InvokeConfig 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					invokeFlag  string