Move ImageName to captain definition

This commit is contained in:
Kasra Bigdeli
2018-12-01 23:37:21 -08:00
parent c9adb55bf9
commit dc0a19de62
7 changed files with 185 additions and 98 deletions
@@ -0,0 +1 @@
//# sourceMappingURL=ICaptainDefinition.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ICaptainDefinition.js","sourceRoot":"","sources":["../../src/models/ICaptainDefinition.ts"],"names":[],"mappings":""}
+61 -35
View File
@@ -67,9 +67,6 @@ class ImageMaker {
* Creates image if necessary, or just simply passes the image name
*/
ensureImage(source, appName, appVersion) {
if (source.sourceImageName) {
return Promise.resolve(source.sourceImageName);
}
const self = this;
this.activeBuilds[appName] = true;
this.buildLogs[appName] =
@@ -81,7 +78,7 @@ class ImageMaker {
const baseDir = self.getDirectoryForRawSource(appName, appVersion);
const rawDir = baseDir + '/' + RAW_SOURCE_DIRECTORY;
const tarFilePath = baseDir + '/' + TAR_FILE_NAME_READY_FOR_DOCKER;
const baseImageNameWithoutVersionAndReg = self.datastore.getImageNameBase(appName); // img-captain--myapp
const baseImageNameWithoutVerAndReg = self.datastore.getImageNameBase(appName); // img-captain--myapp
let fullImageName = ''; // repo.domain.com:998/username/reponame:8
return Promise.resolve() //
.then(function () {
@@ -93,20 +90,14 @@ class ImageMaker {
return self.correctDirectoryAndEnsureCaptainDefinition(rawDir);
})
.then(function (correctedDir) {
return self.convertCaptainDefinitionToDockerfile(correctedDir);
})
.then(function (correctedDir) {
return self.convertContentOfDirectoryIntoTar(correctedDir, tarFilePath);
})
.then(function () {
return self.dockerApi
.buildImageFromDockerFile(baseImageNameWithoutVersionAndReg, appVersion, tarFilePath, self.buildLogs[appName])
.catch(function (error) {
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ('' + error).trim());
return self
.getCaptainDefinition(correctedDir)
.then(function (captainDefinition) {
if (captainDefinition.imageName) {
return captainDefinition.imageName + '';
}
return self.getBuildPushAndReturnImageName(captainDefinition, correctedDir, tarFilePath, baseImageNameWithoutVerAndReg, appName, appVersion);
});
})
.then(function () {
return self.dockerRegistryHelper.retagAndPushIfDefaultPushExist(baseImageNameWithoutVersionAndReg, appVersion, self.buildLogs[appName]);
})
.then(function (ret) {
fullImageName = ret;
@@ -153,6 +144,27 @@ class ImageMaker {
});
});
}
getBuildPushAndReturnImageName(captainDefinition, correctedDirProvided, tarFilePath, baseImageNameWithoutVersionAndReg, appName, appVersion) {
const self = this;
return Promise.resolve() //
.then(function () {
return self
.convertCaptainDefinitionToDockerfile(captainDefinition, correctedDirProvided)
.then(function () {
return self.convertContentOfDirectoryIntoTar(correctedDirProvided, tarFilePath);
})
.then(function () {
return self.dockerApi
.buildImageFromDockerFile(baseImageNameWithoutVersionAndReg, appVersion, tarFilePath, self.buildLogs[appName])
.catch(function (error) {
throw ApiStatusCodes.createError(ApiStatusCodes.BUILD_ERROR, ('' + error).trim());
});
})
.then(function () {
return self.dockerRegistryHelper.retagAndPushIfDefaultPushExist(baseImageNameWithoutVersionAndReg, appVersion, self.buildLogs[appName]);
});
});
}
/**
* Returns a promise that resolve to path a directory where source files + captain definition
*
@@ -218,7 +230,7 @@ class ImageMaker {
});
});
}
convertCaptainDefinitionToDockerfile(directoryWithCaptainDefinition) {
getCaptainDefinition(directoryWithCaptainDefinition) {
return Promise.resolve() //
.then(function () {
return fs.readJson(directoryWithCaptainDefinition +
@@ -232,27 +244,41 @@ class ImageMaker {
if (!data.schemaVersion) {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Captain Definition version is empty!');
}
if (data.schemaVersion === 1) {
const templateIdTag = data.templateId;
const dockerfileLines = data.dockerfileLines;
const hasDockerfileLines = dockerfileLines && dockerfileLines.length > 0;
if (hasDockerfileLines && !templateIdTag) {
return dockerfileLines.join('\n');
}
else if (!hasDockerfileLines && templateIdTag) {
return TemplateHelper.get().getDockerfileContentFromTemplateTag(templateIdTag);
}
else {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Dockerfile or TemplateId must be present. Both should not be present at the same time');
}
if (data.schemaVersion !== 2) {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Captain Definition version is not supported! Read migration guides to schemaVersion 2');
}
const hasTemplateIdTag = !!data.templateId;
const hasImageName = !!data.imageName;
const hasDockerfileLines = data.dockerfileLines && data.dockerfileLines.length > 0;
let numberOfProperties = (hasTemplateIdTag ? 1 : 0) +
(hasImageName ? 1 : 0) +
(hasDockerfileLines ? 1 : 0);
if (numberOfProperties !== 1) {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'One, and only one, of these properties should be present in captain-definition: templateId, imageName, or, hasDockerfileLines');
}
return data;
});
}
convertCaptainDefinitionToDockerfile(captainDefinition, directoryWithCaptainDefinition) {
const self = this;
return Promise.resolve() //
.then(function () {
let data = captainDefinition;
if (data.templateId) {
return TemplateHelper.get().getDockerfileContentFromTemplateTag(data.templateId);
}
else if (data.dockerfileLines) {
return data.dockerfileLines.join('\n');
}
else if (data.imageName) {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'ImageName cannot lead to a dockerfile');
}
else {
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Dockerfile or TemplateId must be present. Both should not be present at the same time');
}
throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'Captain Definition version is not supported!');
})
.then(function (dockerfileContent) {
return fs.outputFile(directoryWithCaptainDefinition + '/' + DOCKER_FILE, dockerfileContent);
})
.then(function () {
return directoryWithCaptainDefinition;
});
}
correctDirectoryAndEnsureCaptainDefinition(originalDirectory) {
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
interface ICaptainDefinition {
schemaVersion: number
dockerfileLines?: string[]
imageName?: string
templateId?: string
}
-1
View File
@@ -1,5 +1,4 @@
interface IImageSource {
sourceImageName?: string
uploadedTarPath?: string
repoInfo?: RepoInfo
captainDefinitionContent?: string
+115 -61
View File
@@ -78,10 +78,6 @@ class ImageMaker {
* Creates image if necessary, or just simply passes the image name
*/
ensureImage(source: IImageSource, appName: string, appVersion: number) {
if (source.sourceImageName) {
return Promise.resolve(source.sourceImageName)
}
const self = this
this.activeBuilds[appName] = true
@@ -97,7 +93,7 @@ class ImageMaker {
const rawDir = baseDir + '/' + RAW_SOURCE_DIRECTORY
const tarFilePath = baseDir + '/' + TAR_FILE_NAME_READY_FOR_DOCKER
const baseImageNameWithoutVersionAndReg = self.datastore.getImageNameBase(
const baseImageNameWithoutVerAndReg = self.datastore.getImageNameBase(
appName
) // img-captain--myapp
let fullImageName = '' // repo.domain.com:998/username/reponame:8
@@ -112,36 +108,23 @@ class ImageMaker {
return self.correctDirectoryAndEnsureCaptainDefinition(rawDir)
})
.then(function(correctedDir) {
return self.convertCaptainDefinitionToDockerfile(correctedDir)
})
.then(function(correctedDir) {
return self.convertContentOfDirectoryIntoTar(
correctedDir,
tarFilePath
)
})
.then(function() {
return self.dockerApi
.buildImageFromDockerFile(
baseImageNameWithoutVersionAndReg,
appVersion,
tarFilePath,
self.buildLogs[appName]
)
.catch(function(error: AnyError) {
throw ApiStatusCodes.createError(
ApiStatusCodes.BUILD_ERROR,
('' + error).trim()
return self
.getCaptainDefinition(correctedDir)
.then(function(captainDefinition) {
if (captainDefinition.imageName) {
return captainDefinition.imageName + ''
}
return self.getBuildPushAndReturnImageName(
captainDefinition,
correctedDir,
tarFilePath,
baseImageNameWithoutVerAndReg,
appName,
appVersion
)
})
})
.then(function() {
return self.dockerRegistryHelper.retagAndPushIfDefaultPushExist(
baseImageNameWithoutVersionAndReg,
appVersion,
self.buildLogs[appName]
)
})
.then(function(ret) {
fullImageName = ret
})
@@ -188,6 +171,53 @@ class ImageMaker {
})
}
private getBuildPushAndReturnImageName(
captainDefinition: ICaptainDefinition,
correctedDirProvided: string,
tarFilePath: string,
baseImageNameWithoutVersionAndReg: string,
appName: string,
appVersion: number
) {
const self = this
return Promise.resolve() //
.then(function() {
return self
.convertCaptainDefinitionToDockerfile(
captainDefinition,
correctedDirProvided
)
.then(function() {
return self.convertContentOfDirectoryIntoTar(
correctedDirProvided,
tarFilePath
)
})
.then(function() {
return self.dockerApi
.buildImageFromDockerFile(
baseImageNameWithoutVersionAndReg,
appVersion,
tarFilePath,
self.buildLogs[appName]
)
.catch(function(error: AnyError) {
throw ApiStatusCodes.createError(
ApiStatusCodes.BUILD_ERROR,
('' + error).trim()
)
})
})
.then(function() {
return self.dockerRegistryHelper.retagAndPushIfDefaultPushExist(
baseImageNameWithoutVersionAndReg,
appVersion,
self.buildLogs[appName]
)
})
})
}
/**
* Returns a promise that resolve to path a directory where source files + captain definition
*
@@ -270,9 +300,7 @@ class ImageMaker {
})
}
private convertCaptainDefinitionToDockerfile(
directoryWithCaptainDefinition: string
) {
private getCaptainDefinition(directoryWithCaptainDefinition: string) {
return Promise.resolve() //
.then(function() {
return fs.readJson(
@@ -281,7 +309,7 @@ class ImageMaker {
CAPTAIN_DEFINITION_FILE
)
})
.then(function(data) {
.then(function(data: ICaptainDefinition) {
if (!data) {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
@@ -296,30 +324,59 @@ class ImageMaker {
)
}
if (data.schemaVersion === 1) {
const templateIdTag = data.templateId
const dockerfileLines: string[] = data.dockerfileLines
const hasDockerfileLines =
dockerfileLines && dockerfileLines.length > 0
if (hasDockerfileLines && !templateIdTag) {
return dockerfileLines.join('\n')
} else if (!hasDockerfileLines && templateIdTag) {
return TemplateHelper.get().getDockerfileContentFromTemplateTag(
templateIdTag
)
} else {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'Dockerfile or TemplateId must be present. Both should not be present at the same time'
)
}
if (data.schemaVersion !== 2) {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'Captain Definition version is not supported! Read migration guides to schemaVersion 2'
)
}
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'Captain Definition version is not supported!'
)
const hasTemplateIdTag = !!data.templateId
const hasImageName = !!data.imageName
const hasDockerfileLines =
data.dockerfileLines && data.dockerfileLines.length > 0
let numberOfProperties =
(hasTemplateIdTag ? 1 : 0) +
(hasImageName ? 1 : 0) +
(hasDockerfileLines ? 1 : 0)
if (numberOfProperties !== 1) {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'One, and only one, of these properties should be present in captain-definition: templateId, imageName, or, hasDockerfileLines'
)
}
return data
})
}
private convertCaptainDefinitionToDockerfile(
captainDefinition: ICaptainDefinition,
directoryWithCaptainDefinition: string
) {
const self = this
return Promise.resolve() //
.then(function() {
let data = captainDefinition
if (data.templateId) {
return TemplateHelper.get().getDockerfileContentFromTemplateTag(
data.templateId
)
} else if (data.dockerfileLines) {
return data.dockerfileLines.join('\n')
} else if (data.imageName) {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'ImageName cannot lead to a dockerfile'
)
} else {
throw ApiStatusCodes.createError(
ApiStatusCodes.STATUS_ERROR_GENERIC,
'Dockerfile or TemplateId must be present. Both should not be present at the same time'
)
}
})
.then(function(dockerfileContent) {
return fs.outputFile(
@@ -327,9 +384,6 @@ class ImageMaker {
dockerfileContent
)
})
.then(function() {
return directoryWithCaptainDefinition
})
}
private correctDirectoryAndEnsureCaptainDefinition(