Refactor the runDockerContainer function to a ContainerRunner interface.

Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com>
This commit is contained in:
Dominik Henneke
2021-04-21 17:14:11 +02:00
parent 044f9930d1
commit e0bfd3d448
39 changed files with 652 additions and 347 deletions
-2
View File
@@ -44,11 +44,9 @@
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.1",
"@google-cloud/storage": "^5.6.0",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"aws-sdk": "^2.840.0",
"cross-fetch": "^3.0.6",
"dockerode": "^3.2.1",
"express": "^4.17.1",
"fs-extra": "^9.0.1",
"git-url-parse": "^11.4.4",
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { ContainerRunner, getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { Generators } from './generators';
import { TechdocsGenerator } from './techdocs';
@@ -30,6 +30,10 @@ const mockEntity = {
};
describe('generators', () => {
const containerRunner: jest.Mocked<ContainerRunner> = {
runContainer: jest.fn(),
};
it('should return error if no generator is registered', async () => {
const generators = new Generators();
@@ -40,7 +44,11 @@ describe('generators', () => {
it('should return correct registered generator', async () => {
const generators = new Generators();
const techdocs = new TechdocsGenerator(logger, new ConfigReader({}));
const techdocs = new TechdocsGenerator({
logger,
containerRunner,
config: new ConfigReader({}),
});
generators.register('techdocs', techdocs);
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { ContainerRunner } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
@@ -30,11 +31,18 @@ export class Generators implements GeneratorBuilder {
static async fromConfig(
config: Config,
{ logger }: { logger: Logger },
{
logger,
containerRunner,
}: { logger: Logger; containerRunner: ContainerRunner },
): Promise<GeneratorBuilder> {
const generators = new Generators();
const techdocsGenerator = new TechdocsGenerator(logger, config);
const techdocsGenerator = new TechdocsGenerator({
logger,
containerRunner,
config,
});
generators.register('techdocs', techdocsGenerator);
return generators;
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { runDockerContainer } from '@backstage/backend-common';
import { ContainerRunner } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import path from 'path';
import { PassThrough } from 'stream';
@@ -48,20 +48,29 @@ const createStream = (): [string[], PassThrough] => {
export class TechdocsGenerator implements GeneratorBase {
private readonly logger: Logger;
private readonly containerRunner: ContainerRunner;
private readonly options: TechdocsGeneratorOptions;
constructor(logger: Logger, config: Config) {
constructor({
logger,
containerRunner,
config,
}: {
logger: Logger;
containerRunner: ContainerRunner;
config: Config;
}) {
this.logger = logger;
this.options = {
runGeneratorIn:
config.getOptionalString('techdocs.generators.techdocs') ?? 'docker',
};
this.containerRunner = containerRunner;
}
public async run({
inputDir,
outputDir,
dockerClient,
parsedLocationAnnotation,
etag,
}: GeneratorRunOptions): Promise<void> {
@@ -100,7 +109,7 @@ export class TechdocsGenerator implements GeneratorBase {
);
break;
case 'docker':
await runDockerContainer({
await this.containerRunner.runContainer({
imageName: 'spotify/techdocs',
args: ['build', '-d', '/output'],
logStream,
@@ -109,7 +118,6 @@ export class TechdocsGenerator implements GeneratorBase {
// Set the home directory inside the container as something that applications can
// write to, otherwise they will just fail trying to write to /
envVars: { HOME: '/tmp' },
dockerClient,
});
this.logger.info(
`Successfully generated docs from ${inputDir} into ${outputDir} using techdocs-container`,
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { Entity } from '@backstage/catalog-model';
import Docker from 'dockerode';
import { Writable } from 'stream';
import { ParsedLocationAnnotation } from '../../helpers';
@@ -23,7 +22,6 @@ import { ParsedLocationAnnotation } from '../../helpers';
*
* @param {string} inputDir The directory of the uncompiled documentation, with the values from the frontend
* @param {string} outputDir Directory to store generated docs in. Usually - a newly created temporary directory.
* @param {Docker} dockerClient A docker client to run any generator on top of your directory
* @param {ParsedLocationAnnotation} parsedLocationAnnotation backstage.io/techdocs-ref annotation of an entity
* @param {string} etag A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json.
* @param {Writable} [logStream] A dedicated log stream
@@ -31,7 +29,6 @@ import { ParsedLocationAnnotation } from '../../helpers';
export type GeneratorRunOptions = {
inputDir: string;
outputDir: string;
dockerClient: Docker;
parsedLocationAnnotation?: ParsedLocationAnnotation;
etag?: string;
logStream?: Writable;