2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright © 2019 Ettore Di Giacinto <mudler@gentoo.org>  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software; you can redistribute it and/or modify  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU General Public License as published by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation; either version 2 of the License, or  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU General Public License for more details.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU General Public License along  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with this program; if not, see <http://www.gnu.org/licenses/>.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  compiler  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 10:22:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									.  "github.com/mudler/luet/pkg/logger" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/mudler/luet/pkg/helpers" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pkg  "github.com/mudler/luet/pkg/package" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/mudler/luet/pkg/solver" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/mudler/luet/pkg/tree" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 10:22:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/pkg/errors" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  BuildFile  =  "build.yaml"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  LuetCompiler  struct  {  
						 
					
						
							
								
									
										
										
										
											2019-11-05 17:36:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									* tree . CompilerRecipe 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									Backend  CompilerBackend 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewLuetCompiler ( backend  CompilerBackend ,  t  pkg . Tree )  Compiler  {  
						 
					
						
							
								
									
										
										
										
											2019-11-05 17:36:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// The CompilerRecipe will gives us a tree with only build deps listed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & LuetCompiler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Backend :  backend , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CompilerRecipe :  & tree . CompilerRecipe { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tree . Recipe { PackageTree :  t } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 10:22:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  compilerWorker ( i  int ,  wg  * sync . WaitGroup ,  cspecs  chan  CompilationSpec ,  a  * [ ] Artifact ,  m  * sync . Mutex ,  concurrency  int ,  keepPermissions  bool ,  errors  chan  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  s  :=  range  cspecs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ar ,  err  :=  cs . Compile ( concurrency ,  keepPermissions ,  s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											errors  <-  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* a  =  append ( * a ,  ar ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  CompileParallel ( concurrency  int ,  keepPermissions  bool ,  ps  [ ] CompilationSpec )  ( [ ] Artifact ,  [ ] error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									all  :=  make ( chan  CompilationSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									artifacts  :=  [ ] Artifact { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mutex  :=  & sync . Mutex { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errors  :=  make ( chan  error ,  len ( ps ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  wg  =  new ( sync . WaitGroup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  concurrency ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  cs . compilerWorker ( i ,  wg ,  all ,  & artifacts ,  mutex ,  concurrency ,  keepPermissions ,  errors ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  p  :=  range  ps  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										all  <-  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( all ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( errors ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  allErrors  [ ] error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  e  :=  range  errors  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										allErrors  =  append ( allErrors ,  e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  artifacts ,  allErrors 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  compileWithImage ( image ,  buildertaggedImage ,  packageImage  string ,  concurrency  int ,  keepPermissions  bool ,  p  CompilationSpec )  ( Artifact ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . SetSeedImage ( image )  // In this case, we ignore the build deps as we suppose that the image has them - otherwise we recompose the tree with a solver, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// and we build all the images first. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									keepImg  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									keepPackageImg  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buildDir  :=  p . Rel ( "build" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-05 17:36:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// First we copy the source definitions into the output - we create a copy which the builds will need (we need to cache this phase somehow) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  helpers . CopyDir ( p . GetPackage ( ) . GetPath ( ) ,  buildDir ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not copy package sources" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  buildertaggedImage  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										keepImg  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buildertaggedImage  =  "luet/"  +  p . GetPackage ( ) . GetFingerPrint ( )  +  "-builder" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  packageImage  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										keepPackageImg  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										packageImage  =  "luet/"  +  p . GetPackage ( ) . GetFingerPrint ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// First we create the builder image 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . WriteBuildImageDefinition ( filepath . Join ( buildDir ,  p . GetPackage ( ) . GetFingerPrint ( ) + "-builder.dockerfile" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									builderOpts  :=  CompilerBackendOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ImageName :       buildertaggedImage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SourcePath :      buildDir , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DockerFileName :  p . GetPackage ( ) . GetFingerPrint ( )  +  "-builder.dockerfile" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Destination :     p . Rel ( p . GetPackage ( ) . GetFingerPrint ( )  +  "-builder.image.tar" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  cs . Backend . BuildImage ( builderOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not build image: " + image + " " + builderOpts . DockerFileName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  cs . Backend . ExportImage ( builderOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not export image" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Then we write the step image, which uses the builder one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p . WriteStepImageDefinition ( buildertaggedImage ,  filepath . Join ( buildDir ,  p . GetPackage ( ) . GetFingerPrint ( ) + ".dockerfile" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									runnerOpts  :=  CompilerBackendOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ImageName :       packageImage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SourcePath :      buildDir , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DockerFileName :  p . GetPackage ( ) . GetFingerPrint ( )  +  ".dockerfile" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Destination :     p . Rel ( p . GetPackage ( ) . GetFingerPrint ( )  +  ".image.tar" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! keepPackageImg  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  cs . Backend . ImageDefinitionToTar ( runnerOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 10:22:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  errors . Wrap ( err ,  "Could not export image to tar" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  cs . Backend . BuildImage ( runnerOpts ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  errors . Wrap ( err ,  "Failed building image for " + runnerOpts . ImageName + " " + runnerOpts . DockerFileName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  cs . Backend . ExportImage ( runnerOpts ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . Wrap ( err ,  "Failed exporting image" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									diffs ,  err  :=  cs . Backend . Changes ( p . Rel ( p . GetPackage ( ) . GetFingerPrint ( ) + "-builder.image.tar" ) ,  p . Rel ( p . GetPackage ( ) . GetFingerPrint ( ) + ".image.tar" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not generate changes from layers" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! keepImg  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We keep them around, so to not reload them from the tar (which should be the "correct way") and we automatically share the same layers 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// TODO: Handle caching and optionally do not remove things 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  cs . Backend . RemoveImage ( builderOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 22:17:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// TODO: Have a --fatal flag which enables Warnings to exit. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Warning ( "Could not remove image " ,  builderOpts . ImageName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//	return nil, errors.Wrap(err, "Could not remove image") 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rootfs ,  err  :=  ioutil . TempDir ( p . GetOutputPath ( ) ,  "rootfs" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not create tempdir" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  os . RemoveAll ( rootfs )  // clean up 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-08 19:57:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TODO: Compression and such 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  cs . Backend . ExtractRootfs ( CompilerBackendOptions { SourcePath :  runnerOpts . Destination ,  Destination :  rootfs } ,  keepPermissions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not extract rootfs" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 17:43:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									artifact ,  err  :=  ExtractArtifactFromDelta ( rootfs ,  p . Rel ( p . GetPackage ( ) . GetFingerPrint ( ) + ".package.tar" ) ,  diffs ,  concurrency ,  keepPermissions ,  p . GetIncludes ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not generate deltas" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  artifact ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 09:42:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  packageFromImage ( p  CompilationSpec ,  tag  string ,  keepPermissions  bool )  ( Artifact ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									builderOpts  :=  CompilerBackendOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ImageName :    p . GetImage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Destination :  p . Rel ( p . GetPackage ( ) . GetFingerPrint ( )  +  ".image.tar" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  cs . Backend . DownloadImage ( builderOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not download image" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  tag  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  cs . Backend . CopyImage ( p . GetImage ( ) ,  tag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . Wrap ( err ,  "Could not download image" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  cs . Backend . ExportImage ( builderOpts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not export image" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rootfs ,  err  :=  ioutil . TempDir ( p . GetOutputPath ( ) ,  "rootfs" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not create tempdir" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  os . RemoveAll ( rootfs )  // clean up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO: Compression and such 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  cs . Backend . ExtractRootfs ( CompilerBackendOptions { SourcePath :  builderOpts . Destination ,  Destination :  rootfs } ,  keepPermissions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Could not extract rootfs" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  helpers . Tar ( rootfs ,  p . Rel ( p . GetPackage ( ) . GetFingerPrint ( ) + ".package.tar" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "Error met while creating package archive" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewPackageArtifact ( p . Rel ( p . GetPackage ( ) . GetFingerPrint ( )  +  ".package.tar" ) ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  Compile ( concurrency  int ,  keepPermissions  bool ,  p  CompilationSpec )  ( Artifact ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Debug ( " 📦 Compiling "  +  p . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 17:31:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  cs . Tree ( ) . ResolveDeps ( concurrency )  // FIXME: When done in parallel, this could be done on top before starting 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 08:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "While resoolving tree world deps" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( p . GetPackage ( ) . GetRequires ( ) )  ==  0  &&  p . GetImage ( )  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error ( "Package with no deps and no seed image supplied, bailing out" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "Package "  +  p . GetPackage ( ) . GetFingerPrint ( )  +  "with no deps and no seed image supplied, bailing out" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// - If image is set we just generate a plain dockerfile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Treat last case (easier) first. The image is provided and we just compute a plain dockerfile with the images listed as above 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  p . GetImage ( )  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 09:42:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  p . ImageUnpack ( )  {  // If it is just an entire image, create a package from it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  cs . packageFromImage ( p ,  "" ,  keepPermissions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  cs . compileWithImage ( p . GetImage ( ) ,  "" ,  "" ,  concurrency ,  keepPermissions ,  p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 17:31:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// - If image is not set, we read a base_image. Then we will build one image from it to kick-off our build based 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// on how we compute the resolvable tree. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This means to recursively build all the build-images needed to reach that tree part. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// - We later on compute an hash used to identify the image, so each similar deptree keeps the same build image. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get build deps tree (ordered) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									world ,  err  :=  cs . Tree ( ) . World ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "While computing tree world" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  solver . NewSolver ( [ ] pkg . Package { } ,  world ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pack ,  err  :=  cs . Tree ( ) . FindPackage ( p . GetPackage ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "While computing a solution for " + p . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									solution ,  err  :=  s . Install ( [ ] pkg . Package { pack } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . Wrap ( err ,  "While computing a solution for " + p . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 17:24:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dependencies  :=  solution . Order ( p . GetPackage ( ) . GetFingerPrint ( ) ) . Drop ( p . GetPackage ( ) )  // at this point we should have a flattened list of deps to build, including all of them (with all constraints propagated already) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									departifacts  :=  [ ] Artifact { }                                                          // TODO: Return this somehow 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deperrs  :=  [ ] error { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  lastHash  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Info ( " 📦 Build dependencies: ( target " + p . GetPackage ( ) . GetName ( ) + ")" ,  dependencies . Explain ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  assertion  :=  range  dependencies  {  //highly dependent on the order 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  assertion . Value  &&  assertion . Package . Flagged ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Info ( "( 📦 target " + p . GetPackage ( ) . GetName ( ) + ") Building" ,  assertion . Package . GetName ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											compileSpec ,  err  :=  cs . FromPackage ( assertion . Package ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  errors . New ( "Error while generating compilespec for "  +  assertion . Package . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											compileSpec . SetOutputPath ( p . GetOutputPath ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											depPack ,  err  :=  cs . Tree ( ) . FindPackage ( assertion . Package ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  errors . Wrap ( err ,  "While computing a solution for " + p . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Generate image name of builder image - it should match with the hash up to this point - package 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nthsolution ,  err  :=  s . Install ( [ ] pkg . Package { depPack } ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  errors . Wrap ( err ,  "While computing a solution for " + p . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 17:24:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buildImageHash  :=  "luet/cache:"  +  nthsolution . Order ( depPack . GetFingerPrint ( ) ) . Drop ( depPack ) . AssertionHash ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											currentPackageImageHash  :=  "luet/cache:"  +  nthsolution . Order ( depPack . GetFingerPrint ( ) ) . AssertionHash ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Debug ( "( 📦" + p . GetPackage ( ) . GetName ( ) + ") 🐋 Builder image name:" ,  buildImageHash ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Debug ( "( 📦 " + p . GetPackage ( ) . GetName ( ) + ") 🐋 Package image name:" ,  currentPackageImageHash ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 00:13:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											lastHash  =  currentPackageImageHash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  compileSpec . GetImage ( )  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 09:42:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// TODO: Refactor this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  p . ImageUnpack ( )  {  // If it is just an entire image, create a package from it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													artifact ,  err  :=  cs . packageFromImage ( p ,  currentPackageImageHash ,  keepPermissions ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														deperrs  =  append ( deperrs ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break  // stop at first error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													departifacts  =  append ( departifacts ,  artifact ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Debug ( " 📦 ("  +  p . GetPackage ( ) . GetName ( )  +  ") Compiling "  +  compileSpec . GetPackage ( ) . GetFingerPrint ( )  +  " from image" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												artifact ,  err  :=  cs . compileWithImage ( compileSpec . GetImage ( ) ,  buildImageHash ,  currentPackageImageHash ,  concurrency ,  keepPermissions ,  compileSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													deperrs  =  append ( deperrs ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break  // stop at first error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												departifacts  =  append ( departifacts ,  artifact ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											artifact ,  err  :=  cs . compileWithImage ( buildImageHash ,  "" ,  currentPackageImageHash ,  concurrency ,  keepPermissions ,  compileSpec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  errors . Wrap ( err ,  "Failed compiling " + compileSpec . GetPackage ( ) . GetName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//	deperrs = append(deperrs, err) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//		break // stop at first error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											departifacts  =  append ( departifacts ,  artifact ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-05 17:36:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:14:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Debug ( " 📦 (" + p . GetPackage ( ) . GetName ( ) + ") Building target from" ,  lastHash ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-05 17:36:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-11 19:19:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  cs . compileWithImage ( lastHash ,  "" ,  "" ,  concurrency ,  keepPermissions ,  p ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  FromPackage ( p  pkg . Package )  ( CompilationSpec ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-12 17:26:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pack ,  err  :=  cs . Tree ( ) . FindPackage ( p ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									buildFile  :=  pack . Rel ( BuildFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! helpers . Exists ( buildFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "No build file present for "  +  p . GetFingerPrint ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dat ,  err  :=  ioutil . ReadFile ( buildFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 10:48:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NewLuetCompilationSpec ( dat ,  pack ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:16:13 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-11-04 17:20:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  GetBackend ( )  CompilerBackend  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cs . Backend 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( cs  * LuetCompiler )  SetBackend ( b  CompilerBackend )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cs . Backend  =  b 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}