@adp-psych/container-tools
Version:
Tools for using containers for psychology experiments
119 lines (110 loc) • 3.71 kB
JavaScript
/*
* Copyright (C) 2020, 2021 Anthony Di Pietro
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* @file Builds a container using [buildah](https://buildah.io/).
*
* @module module:build-container
* @requires console-exec
* @author Anthony Di Pietro <anthony.dipietro@research.uwa.edu.au>
* @copyright © 2020, 2021 Anthony Di Pietro
* @license AGPL-3.0-or-later
*/
const {'execFile': callbackExecFile} = require('node:child_process');
const {promisify} = require('node:util');
const pkgBasename = require('@adp-psych/pkg-basename');
const readPkgUp = require('read-pkg-up');
const {consoleSpawn} = require('./console-exec.js');
const execFile = promisify(callbackExecFile);
/* eslint-disable jsdoc/match-description -- Irregular start. */
/**
* [Describes](https://git-scm.com/docs/git-describe) the
* [Git](https://git-scm.com/) reference of the current directory.
*
* @static
* @access protected
* @returns {String} The description of the Git reference.
* @example
* gitDescription(); // The description of the Git reference.
*/
const gitDescription = async () => {
try {
const {stdout} = await execFile('git', ['describe', '--dirty']);
return stdout.replace(/\n$/u, '');
} catch {
return '';
}
};
/* eslint-enable jsdoc/match-description -- Reenabling. */
/**
* Builds a container using buildah.
*
* @static
* @param {String} containerDirectory - The container source directory.
* @param {String} tagSuffix - The suffix of the container tag.
* @example
* // Builds the experiment container from the current directory.
* buildContainer('.', 'experiment');
*/
const buildContainer = async (containerDirectory, tagSuffix = '') => {
const isoTimestamp = new Date().toISOString();
const packageBasename = pkgBasename();
const {'packageJson': pkg} = await readPkgUp();
const revision = await gitDescription();
const tag = tagSuffix === '' ?
packageBasename :
`${packageBasename}-${tagSuffix}`;
const originalDirectory = process.cwd();
process.chdir(containerDirectory);
await consoleSpawn('buildah', [
'bud',
'--label',
`org.opencontainers.image.created=${isoTimestamp}`,
'--label',
`org.opencontainers.image.authors=${pkg.author.url}`,
'--label',
`org.opencontainers.image.url=${pkg.author.url}`,
'--label',
`org.opencontainers.image.documentation=${pkg.author.url}`,
'--label',
`org.opencontainers.image.source=${pkg.author.url}`,
'--label',
`org.opencontainers.image.version=${pkg.version}`,
...revision === '' ?
[] :
[
'--label',
`org.opencontainers.image.revision=${revision}`,
],
'--label',
`org.opencontainers.image.vendor=${pkg.author.name}`,
'--label',
`org.opencontainers.image.licenses=${pkg.license}`,
'--label',
'org.opencontainers.image.ref.name=latest',
'--label',
`org.opencontainers.image.title=${packageBasename}`,
'--label',
`org.opencontainers.image.description=${pkg.description}`,
'--build-arg',
`PKG_BASENAME=${packageBasename}`,
'--tag',
tag,
'.',
]);
process.chdir(originalDirectory);
};
module.exports = buildContainer;