| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  | import { logger } from '../npmci.logging'; | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  | import * as plugins from './mod.plugins'; | 
					
						
							|  |  |  | import * as paths from '../npmci.paths'; | 
					
						
							|  |  |  | import * as NpmciEnv from '../npmci.env'; | 
					
						
							|  |  |  | import * as NpmciConfig from '../npmci.config'; | 
					
						
							|  |  |  | import { bash } from '../npmci.bash'; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  | import { Dockerfile } from './mod.classes.dockerfile'; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * creates instance of class Dockerfile for all Dockerfiles in cwd | 
					
						
							|  |  |  |  * @returns Promise<Dockerfile[]> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let readDockerfiles = async (): Promise<Dockerfile[]> => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*'); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // create the Dockerfile array
 | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const readDockerfilesArray: Dockerfile[] = []; | 
					
						
							|  |  |  |   logger.log('info', `found ${fileTree.length} Dockerfiles:`); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   console.log(fileTree); | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   for (const dockerfilePath of fileTree) { | 
					
						
							|  |  |  |     const myDockerfile = new Dockerfile({ | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |       filePath: dockerfilePath, | 
					
						
							|  |  |  |       read: true | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  |     readDockerfilesArray.push(myDockerfile); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return readDockerfilesArray; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * sorts Dockerfiles into a dependency chain | 
					
						
							|  |  |  |  * @param sortableArrayArg an array of instances of class Dockerfile | 
					
						
							|  |  |  |  * @returns Promise<Dockerfile[]> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const done = plugins.smartpromise.defer<Dockerfile[]>(); | 
					
						
							|  |  |  |   logger.log('info', 'sorting Dockerfiles:'); | 
					
						
							|  |  |  |   const sortedArray: Dockerfile[] = []; | 
					
						
							|  |  |  |   const cleanTagsOriginal = cleanTagsArrayFunction(sortableArrayArg, sortedArray); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   let sorterFunctionCounter: number = 0; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const sorterFunction = () => { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     sortableArrayArg.forEach(dockerfileArg => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |       const cleanTags = cleanTagsArrayFunction(sortableArrayArg, sortedArray); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       if ( | 
					
						
							|  |  |  |         cleanTags.indexOf(dockerfileArg.baseImage) === -1 && | 
					
						
							|  |  |  |         sortedArray.indexOf(dockerfileArg) === -1 | 
					
						
							|  |  |  |       ) { | 
					
						
							|  |  |  |         sortedArray.push(dockerfileArg); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |         dockerfileArg.localBaseImageDependent = true; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     if (sortableArrayArg.length === sortedArray.length) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       let counter = 1; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |       for (const dockerfile of sortedArray) { | 
					
						
							|  |  |  |         logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |         counter++; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       done.resolve(sortedArray); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     } else if (sorterFunctionCounter < 10) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       sorterFunctionCounter++; | 
					
						
							|  |  |  |       sorterFunction(); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  |   sorterFunction(); | 
					
						
							|  |  |  |   return done.promise; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let mapDockerfiles = async (sortedArray: Dockerfile[]): Promise<Dockerfile[]> => { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   sortedArray.forEach(dockerfileArg => { | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     if (dockerfileArg.localBaseImageDependent) { | 
					
						
							|  |  |  |       sortedArray.forEach((dockfile2: Dockerfile) => { | 
					
						
							|  |  |  |         if (dockfile2.cleanTag === dockerfileArg.baseImage) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |           dockerfileArg.localBaseDockerfile = dockfile2; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  |   return sortedArray; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * builds the correspoding real docker image for each Dockerfile class instance | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   for (const dockerfileArg of sortedArrayArg) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     await dockerfileArg.build(); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return sortedArrayArg; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * tests all Dockerfiles in by calling class Dockerfile.test(); | 
					
						
							|  |  |  |  * @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   for (const dockerfileArg of sortedArrayArg) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     await dockerfileArg.test(); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return sortedArrayArg; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * returns a version for a docker file | 
					
						
							|  |  |  |  * @execution SYNC | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export let dockerFileVersion = (dockerfileNameArg: string): string => { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   let versionString: string; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; | 
					
						
							|  |  |  |   const regexResultArray = versionRegex.exec(dockerfileNameArg); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   if (regexResultArray && regexResultArray.length === 2) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     versionString = regexResultArray[1]; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     versionString = 'latest'; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return versionString; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * returns the docker base image for a Dockerfile | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  | export let dockerBaseImage = (dockerfileContentArg: string) => { | 
					
						
							|  |  |  |   const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/; | 
					
						
							|  |  |  |   const regexResultArray = baseImageRegex.exec(dockerfileContentArg); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return regexResultArray[1]; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * returns the docker tag | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  | export let getDockerTagString = ( | 
					
						
							|  |  |  |   registryArg: string, | 
					
						
							|  |  |  |   repoArg: string, | 
					
						
							|  |  |  |   versionArg: string, | 
					
						
							|  |  |  |   suffixArg?: string | 
					
						
							|  |  |  | ): string => { | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  |   // determine wether the repo should be mapped accordingly to the registry
 | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const mappedRepo = NpmciConfig.configObject.dockerRegistryRepoMap[registryArg]; | 
					
						
							|  |  |  |   const repo = (() => { | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  |     if (mappedRepo) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       return mappedRepo; | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       return repoArg; | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   })(); | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // determine wether the version contais a suffix
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   let version = versionArg; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   if (suffixArg) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     version = versionArg + '_' + suffixArg; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-08-28 18:09:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   const tagString = `${registryArg}/${repo}:${version}`; | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return tagString; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-28 19:11:24 +02:00
										 |  |  | export let getDockerBuildArgs = async (): Promise<string> => { | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   logger.log('info', 'checking for env vars to be supplied to the docker build'); | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   let buildArgsString: string = ''; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  |   for (const key in NpmciConfig.configObject.dockerBuildargEnvMap) { | 
					
						
							|  |  |  |     const targetValue = process.env[NpmciConfig.configObject.dockerBuildargEnvMap[key]]; | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |     buildArgsString = `${buildArgsString} --build-arg ${key}=${targetValue}`; | 
					
						
							| 
									
										
										
										
											2017-08-28 19:11:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   return buildArgsString; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-08-28 19:11:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  | export let cleanTagsArrayFunction = ( | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   dockerfileArrayArg: Dockerfile[], | 
					
						
							|  |  |  |   trackingArrayArg: Dockerfile[] | 
					
						
							| 
									
										
										
										
											2018-11-24 15:00:19 +01:00
										 |  |  | ): string[] => { | 
					
						
							|  |  |  |   const cleanTagsArray: string[] = []; | 
					
						
							| 
									
										
										
										
											2018-11-24 15:10:55 +01:00
										 |  |  |   dockerfileArrayArg.forEach(dockerfileArg => { | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     if (trackingArrayArg.indexOf(dockerfileArg) === -1) { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |       cleanTagsArray.push(dockerfileArg.cleanTag); | 
					
						
							| 
									
										
										
										
											2017-08-28 01:03:59 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:25:13 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  |   return cleanTagsArray; | 
					
						
							|  |  |  | }; |