Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manifest #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
.idea
.vscode
*.iml
openjdk-6
openjdk-7
Expand Down
1 change: 1 addition & 0 deletions example/java/blocks/qemu-lib-arm64v8/commands.dck
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
COPY qemu-aarch64-static /usr/bin/
Binary file not shown.
6 changes: 6 additions & 0 deletions example/java/images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fish-pepper:
params:
- "version"
- "type"
- "arch"
# Name stem to use for the images to create with -b (param value will be appended with -)
name: "jolokia/fish-pepper-java"
# Internal build number. Should be increased for each change
Expand Down Expand Up @@ -41,3 +42,8 @@ config:
extension: "-jre"
jdk:
extension: "-jdk"
arch:
amd64:
dockerOrg: "p31amd64"
arm64v8:
dockerOrg: "p31arm64v8"
8 changes: 8 additions & 0 deletions example/java/push-images.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
docker push docker.io/p31amd64/fish-pepper-java-openjdk7-jdk-amd64:1.7-2
docker push docker.io/p31arm64v8/fish-pepper-java-openjdk7-jdk-arm64v8:1.7-2
docker push docker.io/p31amd64/fish-pepper-java-openjdk7-jre-amd64:1.7-2
docker push docker.io/p31arm64v8/fish-pepper-java-openjdk7-jre-arm64v8:1.7-2
docker push docker.io/p31amd64/fish-pepper-java-openjdk8-jdk-amd64:1.8-2
docker push docker.io/p31arm64v8/fish-pepper-java-openjdk8-jdk-arm64v8:1.8-2
docker push docker.io/p31amd64/fish-pepper-java-openjdk8-jre-amd64:1.8-2
docker push docker.io/p31arm64v8/fish-pepper-java-openjdk8-jre-arm64v8:1.8-2
1 change: 1 addition & 0 deletions example/java/templates/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM {{= fp.config.version.java + fp.config.type.extension }}
{{= fp.block("qemu-lib-" + fp.param.arch,'commands',{'fp-bin-files' : true}) || ''}}

MAINTAINER {{= fp.maintainer }}

Expand Down
44 changes: 43 additions & 1 deletion fish-pepper.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var templateEngine = require('./fp/template-engine');
var dockerBackend = require('./fp/docker-backend');
var blockLoader = require('./fp/block-loader');
var imageBuilder = require('./fp/image-builder');
var manifestBuilder = require('./fp/manifest-builder');

var util = require('./fp/util');

Expand Down Expand Up @@ -50,6 +51,11 @@ function processImages(ctx, images) {
if (ctx.commands.build) {
buildImages(ctx, images);
}

// If desired create Docker manifests
if (ctx.commands.manifest) {
buildManifests(ctx, images);
}
}

// == COMMMANDS ===========================================================================
Expand All @@ -73,6 +79,12 @@ function buildImages(ctx, images) {

var docker = dockerBackend.create(ctx.options);

fs.open('push-images.log', 'w', function(err, fd) {
fs.close(fd, function() {
console.log('truncated \'push-images.log\' successfully');
});
});

images.forEach(function(image) {
console.log(" " + image.dir.magenta);
var params = extractParams(image, ctx);
Expand All @@ -82,7 +94,33 @@ function buildImages(ctx, images) {
},createParamIgnoreMap(image));
imageBuilder.build(ctx.root, docker, params.types, valuesExpanded, image, { nocache: ctx.options.nocache, debug: DEBUG });
});

}

// "manifest"
function buildManifests(ctx, images) {
console.log("\n* " + "Building Manifests".cyan);

var docker = dockerBackend.create(ctx.options);

fs.open('manifest.log', 'w', function(err, fd) {
fs.close(fd, function() {
console.log('\'manifest.log\' written');
});
});

images.forEach(function(image) {
console.log(" " + image.dir.magenta);
var params = extractParams(image, ctx, 'arch');
var valuesExpanded = [];
util.foreachParamValue(params,function(values) {
valuesExpanded.push(values);
},createParamIgnoreMap(image));
manifestBuilder.build(ctx.root, docker, params.types, valuesExpanded, image, { nocache: ctx.options.nocache, debug: DEBUG });
});

}

// ===================================================================================

function getImages(ctx) {
Expand Down Expand Up @@ -161,7 +199,7 @@ function getImageConfig(ctx, image) {
}

// Return all params in the right order and the individual configuration per param
function extractParams(image, ctx) {
function extractParams(image, ctx, reduceValue) {
var config = image.config;
var types = config.fpConfig('params').slice(0);
var paramValues = undefined;
Expand All @@ -171,6 +209,10 @@ function extractParams(image, ctx) {
paramValues = extractFixedParamValues(opts, ctx.root + "/" + image.dir);
paramConfigs = opts.experimental || paramValues ? config.config : removeExperimentalConfigs(config.config);
}

if (reduceValue) {
types.pop();
}

// Filter out configuration which are not selected by the user
var reducedParamConfig = reduceConfig(types,paramConfigs,paramValues);
Expand Down
7 changes: 6 additions & 1 deletion fp/image-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ var imageNames = require('./image-names');
var tarCmd = "tar";
var child = require('child_process');
var stream = require('stream');
const fs = require('fs');

exports.build = function(root, docker, types, allParamValues, image, opts) {
doBuildImages(root, docker, imageNames.createImageNames(image, types, allParamValues),opts);
};

function doBuildImages(root, docker, imageNames, opts) {
if (imageNames && imageNames.length > 0) {

var imageName = imageNames.shift();
console.log(" " + imageName.getLabel().green + " --> " + imageName.getImageNameWithVersion().cyan);

var fullName = imageName.getImageNameWithVersion();

var image = docker.getImage(fullName);
image.inspect(function (error, data) {
if (!error) {
Expand Down Expand Up @@ -56,6 +58,9 @@ function doBuildImages(root, docker, imageNames, opts) {
throw error;
}
});
let writeStream = fs.createWriteStream('push-images.log', {flags: 'a'});
writeStream.write('docker push ' + imageName.getImageNameWithVersion() + '\n');
writeStream.end();
}
}

Expand Down
29 changes: 28 additions & 1 deletion fp/image-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ exports.createImageNames = function(image,paramTypes, allParamValues) {
function createImageName(image, types, paramValues) {
return {
getPath: function (root) {

return root + "/" + image.dir + "/images/" + paramValues.join("/");
},

Expand All @@ -35,15 +36,41 @@ function createImageName(image, types, paramValues) {
}
});
return ret;
},

getShortName: function () {
var shortName = getImageName();
if (shortName.indexOf("/") > 0) {
shortName = shortName.substring(shortName.indexOf("/") + 1);
}
return shortName;
}
};

// ==========================================================================================

function getImageName()
{
var dockerOrg = getDockerOrg();
var name = image.name;
if (dockerOrg && name.includes("/")) {
name = dockerOrg + name.substring(name.indexOf("/"));
}
var registry = image.config.fpConfig('registry') ? image.config.fpConfig('registry') + "/" : "";
return registry + image.name + "-" + paramValues.join("-");
return registry + name + "-" + paramValues.join("-");
}

function getDockerOrg()
{
var dockerOrg = undefined;
for (type in types) {
var param = paramValues[type];
var org = image.config.config[types[type]][param].dockerOrg;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every parameter which has a meaning for fish-pepper should go below the fish-pepper configuration section. Everything else can be introduced and changed by the user freely. So that kind of dockerOrg should not into this section where the user has the full control of all parameter keys.

if (org) {
dockerOrg = org;
}
}
return dockerOrg;
}

function getVersion() {
Expand Down
58 changes: 58 additions & 0 deletions fp/manifest-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
var imageNames = require('./image-names');
var child = require('child_process');
var stream = require('stream');
const fs = require('fs');
var readline = require('readline');

exports.build = function(root, docker, types, allParamValues, image, opts) {
doBuildManifests(root, docker, imageNames.createImageNames(image, types, allParamValues),opts);
};

function doBuildManifests(root, docker, imageNames, opts) {
//for now we only support amd64 and arm64v8
var arch = ['arm64v8'];
var anno = [' --os linux --arch arm64 --variant armv8'];
if (imageNames && imageNames.length > 0) {

var imageName = imageNames.shift();
var shortName = imageName.getShortName();
console.log(" " + imageName.getLabel().green + " --> " + imageName.getImageNameWithVersion().cyan);

var manifest = 'docker manifest create ' + imageName.getImageNameWithVersion();
var archImageNames = findImagesInFile(shortName);
for (var i in archImageNames) {
manifest = manifest + ' ' + archImageNames[i];
}
manifest = manifest + '\n';

for (var i in arch) {
for (var j in archImageNames) {
if (archImageNames[j].includes(arch[i])) {
var annotation = 'docker manifest annotate ' + imageName.getImageNameWithVersion();
annotation = annotation + ' ' + archImageNames[j] + anno[i];
manifest = manifest + annotation + '\n';
}
}
}
manifest = manifest + 'docker manifest push ' + imageName.getImageNameWithVersion() + '\n\n';
writeStream = fs.createWriteStream('manifest.log', {flags: 'a'});
writeStream.write(manifest);
writeStream.end();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens with the manifest except than get written to a log file ?


doBuildManifests(root, docker, imageNames, opts);
}

}

function findImagesInFile(arch) {
var lines = fs.readFileSync('push-images.log', 'utf-8')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be better to pick the image names from the configuration than from a log file which adds some dependencies on your the user's usage flow ? Looking up the config like 'build' does shouldn't be that hard here, too.

.split('\n')
.filter(function (line) {
return line.includes(arch);
});
var names = [];
for (var i in lines) {
names.push(lines[i].substring(12));
}
return names;
}
21 changes: 20 additions & 1 deletion fp/template-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,33 @@ exports.fillTemplates = function (ctx, image, params, blocks, paramIgnoreMap) {

// Copy over files attached to block if changed
if (!opts["fp-no-files"]) {
copyBlockFiles(key, templateContext, paramValues);
if (opts["fp-bin-files"]) {
copyBlockBinaryFiles(key, paramValues);
} else {
copyBlockFiles(key, templateContext, paramValues);
}
}
return blocks[key]["text"] && blocks[key]["text"][subSnippet] ?
(dot.template(blocks[key]["text"][subSnippet]))(templateContext) :
undefined;
}
}

function copyBlockBinaryFiles(key, paramValues) {
var files = blocks[key].files || [];
files.forEach(function (file) {
var base = path.parse(file).base;
var targetFile = getPath(paramValues, base);
var existingFile = fs.existsSync(targetFile);
var newSize = fs.statSync(file).size;
var oldSize = existingFile ? fs.statSync(targetFile).size : 0;
if (! existingFile || newSize != oldSize) {
fs.copyFileSync(file, targetFile);
logFile(file, !existingFile ? "NEW".yellow : "CHANGED".green, key);
}
});
}

function copyBlockFiles(key, templateContext, paramValues) {
var files = blocks[key].files || [];
files.forEach(function (file) {
Expand Down
Loading