Merge pull request #5415 from SDA-SE/feat/rundocker-api

Refactor the runDockerContainer function to a ContainerRunnerApi interface
This commit is contained in:
Dominik Henneke
2021-05-05 12:00:40 +02:00
committed by GitHub
41 changed files with 689 additions and 371 deletions
+56
View File
@@ -0,0 +1,56 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`.
It also provides the `ContainerRunner` to the individual templaters instead of to the `createRouter` function.
To apply this change to an existing backend application, add the following to `src/plugins/scaffolder.ts`:
```diff
- import { SingleHostDiscovery } from '@backstage/backend-common';
+ import {
+ DockerContainerRunner,
+ SingleHostDiscovery,
+ } from '@backstage/backend-common';
export default async function createPlugin({
logger,
config,
database,
reader,
}: PluginEnvironment): Promise<Router> {
+ const dockerClient = new Docker();
+ const containerRunner = new DockerContainerRunner({ dockerClient });
+ const cookiecutterTemplater = new CookieCutter({ containerRunner });
- const cookiecutterTemplater = new CookieCutter();
+ const craTemplater = new CreateReactAppTemplater({ containerRunner });
- const craTemplater = new CreateReactAppTemplater();
const templaters = new Templaters();
templaters.register('cookiecutter', cookiecutterTemplater);
templaters.register('cra', craTemplater);
const preparers = await Preparers.fromConfig(config, { logger });
const publishers = await Publishers.fromConfig(config, { logger });
- const dockerClient = new Docker();
const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
- dockerClient,
database,
catalogClient,
reader,
});
}
```
+58
View File
@@ -0,0 +1,58 @@
---
'@backstage/backend-common': minor
---
Refactor the `runDockerContainer(…)` function to an interface-based api.
This gives the option to replace the docker runtime in the future.
Packages and plugins that previously used the `dockerode` as argument should be migrated to use the new `ContainerRunner` interface instead.
```diff
import {
- runDockerContainer,
+ ContainerRunner,
PluginEndpointDiscovery,
} from '@backstage/backend-common';
- import Docker from 'dockerode';
type RouterOptions = {
// ...
- dockerClient: Docker,
+ containerRunner: ContainerRunner;
};
export async function createRouter({
// ...
- dockerClient,
+ containerRunner,
}: RouterOptions): Promise<express.Router> {
// ...
+ await containerRunner.runContainer({
- await runDockerContainer({
image: 'docker',
// ...
- dockerClient,
});
// ...
}
```
To keep the `dockerode` based runtime, use the `DockerContainerRunner` implementation:
```diff
+ import {
+ ContainerRunner,
+ DockerContainerRunner
+ } from '@backstage/backend-common';
- import { runDockerContainer } from '@backstage/backend-common';
+ const containerRunner: ContainerRunner = new DockerContainerRunner({dockerClient});
+ await containerRunner.runContainer({
- await runDockerContainer({
image: 'docker',
// ...
- dockerClient,
});
```
+61
View File
@@ -0,0 +1,61 @@
---
'@backstage/plugin-techdocs-backend': minor
---
Migrate the plugin to use the `ContainerRunner` interface instead of `runDockerContainer(…)`.
It also provides the `ContainerRunner` to the generators instead of to the `createRouter` function.
To apply this change to an existing backend application, add the following to `src/plugins/techdocs.ts`:
```diff
+ import { DockerContainerRunner } from '@backstage/backend-common';
// ...
export default async function createPlugin({
logger,
config,
discovery,
reader,
}: PluginEnvironment): Promise<Router> {
// Preparers are responsible for fetching source files for documentation.
const preparers = await Preparers.fromConfig(config, {
logger,
reader,
});
+ // Docker client (conditionally) used by the generators, based on techdocs.generators config.
+ const dockerClient = new Docker();
+ const containerRunner = new DockerContainerRunner({ dockerClient });
// Generators are used for generating documentation sites.
const generators = await Generators.fromConfig(config, {
logger,
+ containerRunner,
});
// Publisher is used for
// 1. Publishing generated files to storage
// 2. Fetching files from storage and passing them to TechDocs frontend.
const publisher = await Publisher.fromConfig(config, {
logger,
discovery,
});
// checks if the publisher is working and logs the result
await publisher.getReadiness();
- // Docker client (conditionally) used by the generators, based on techdocs.generators config.
- const dockerClient = new Docker();
return await createRouter({
preparers,
generators,
publisher,
- dockerClient,
logger,
config,
discovery,
});
}
```
+27
View File
@@ -0,0 +1,27 @@
---
'@backstage/techdocs-common': minor
---
Migrate the package to use the `ContainerRunner` interface instead of `runDockerContainer(…)`.
It also no longer provides the `ContainerRunner` as an input to the `GeneratorBase#run(…)` function, but expects it as a constructor parameter instead.
If you use the `TechdocsGenerator` you need to update the usage:
```diff
+ const containerRunner = new DockerContainerRunner({ dockerClient });
- const generator = new TechdocsGenerator(logger, config);
+ const techdocsGenerator = new TechdocsGenerator({
+ logger,
+ containerRunner,
+ config,
+ });
await this.generator.run({
inputDir: preparedDir,
outputDir,
- dockerClient: this.dockerClient,
parsedLocationAnnotation,
etag: newEtag,
});
```
+115
View File
@@ -0,0 +1,115 @@
---
'@backstage/create-app': patch
---
The `scaffolder-backend` and `techdocs-backend` plugins have been updated.
In order to update, you need to apply the following changes to your existing backend application:
`@backstage/plugin-techdocs-backend`:
```diff
// packages/backend/src/plugin/techdocs.ts
+ import { DockerContainerRunner } from '@backstage/backend-common';
// ...
export default async function createPlugin({
logger,
config,
discovery,
reader,
}: PluginEnvironment): Promise<Router> {
// Preparers are responsible for fetching source files for documentation.
const preparers = await Preparers.fromConfig(config, {
logger,
reader,
});
+ // Docker client (conditionally) used by the generators, based on techdocs.generators config.
+ const dockerClient = new Docker();
+ const containerRunner = new DockerContainerRunner({ dockerClient });
// Generators are used for generating documentation sites.
const generators = await Generators.fromConfig(config, {
logger,
+ containerRunner,
});
// Publisher is used for
// 1. Publishing generated files to storage
// 2. Fetching files from storage and passing them to TechDocs frontend.
const publisher = await Publisher.fromConfig(config, {
logger,
discovery,
});
// checks if the publisher is working and logs the result
await publisher.getReadiness();
- // Docker client (conditionally) used by the generators, based on techdocs.generators config.
- const dockerClient = new Docker();
return await createRouter({
preparers,
generators,
publisher,
- dockerClient,
logger,
config,
discovery,
});
}
```
`@backstage/plugin-scaffolder-backend`:
```diff
// packages/backend/src/plugin/scaffolder.ts
- import { SingleHostDiscovery } from '@backstage/backend-common';
+ import {
+ DockerContainerRunner,
+ SingleHostDiscovery,
+ } from '@backstage/backend-common';
export default async function createPlugin({
logger,
config,
database,
reader,
}: PluginEnvironment): Promise<Router> {
+ const dockerClient = new Docker();
+ const containerRunner = new DockerContainerRunner({ dockerClient });
+ const cookiecutterTemplater = new CookieCutter({ containerRunner });
- const cookiecutterTemplater = new CookieCutter();
+ const craTemplater = new CreateReactAppTemplater({ containerRunner });
- const craTemplater = new CreateReactAppTemplater();
const templaters = new Templaters();
templaters.register('cookiecutter', cookiecutterTemplater);
templaters.register('cra', craTemplater);
const preparers = await Preparers.fromConfig(config, { logger });
const publishers = await Publishers.fromConfig(config, { logger });
- const dockerClient = new Docker();
const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
preparers,
templaters,
publishers,
logger,
config,
- dockerClient,
database,
catalogClient,
reader,
});
}
```