Skip to content

Commit

Permalink
Add docker pack
Browse files Browse the repository at this point in the history
Add docker pack to this library, excepting fingerprint support.

[changelog:added]
  • Loading branch information
David Dooling committed Jun 24, 2020
1 parent 697144b commit 79906fc
Show file tree
Hide file tree
Showing 14 changed files with 1,300 additions and 3 deletions.
173 changes: 173 additions & 0 deletions lib/core/pack/docker/build/DockerBuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* Copyright © 2020 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Goal, GoalDefinition } from "../../../../api/goal/Goal";
import { DefaultGoalNameGenerator } from "../../../../api/goal/GoalNameGenerator";
import {
FulfillableGoalDetails,
FulfillableGoalWithRegistrations,
getGoalDefinitionFrom,
ImplementationRegistration,
mergeOptions,
} from "../../../../api/goal/GoalWithFulfillment";
import { IndependentOfEnvironment } from "../../../../api/goal/support/environment";
import { GitProject } from "../../../../client";
import { DockerProgressReporter } from "./DockerProgressReporter";
import { DefaultDockerImageNameCreator, DockerImageNameCreator, executeDockerBuild } from "./executeDockerBuild";

export interface DockerRegistry {
/**
* Push Url for this registry
*/
registry: string;

/**
* Should this registry be displayed with the goal status after a push? Default true.
*/
display?: boolean;

/**
* Display Url - ie the url humans can go to
* assumes <url>/<image>
*/
displayUrl?: string;

/**
* If specified, this will replace the label version details (eg <image><:version>)
* For example, for Dockerhub the correct value would be `/tags`, with a displayUrl set
* to https://hub.docker.com/r/<user/org>; will result in:
* https://hub.docker.com/r/<user/org>/<image>/tags as the link URL
*
*/
displayBrowsePath?: string;

/**
* How should urls to this registry be labeled?
* ie DockerHub, ECR, etc (friendly name instead of big tag string)
* if not supplied, we'll display the tag
*/
label?: string;

user?: string;
password?: string;
}

/**
* Options to configure the Docker image build
*/
export interface DockerOptions extends Partial<ImplementationRegistration> {
/**
* Provide the image tag for the docker image to build
*/
dockerImageNameCreator?: DockerImageNameCreator;

/**
* True if the docker image should be pushed to the registry
*/
push?: boolean;

/**
* True if pushes should happen concurrently
*/
concurrentPush?: boolean;

/**
* Optional registries to push the docker image too.
* Needs to set when push === true
*/
registry?: DockerRegistry | DockerRegistry[];

/**
* Optional Docker config in json as alternative to running
* 'docker login' with provided registry, user and password.
*/
config?: string;

/**
* Find the Dockerfile within the project
* @param p the project
*/
dockerfileFinder?: (p: GitProject) => Promise<string>;

/**
* Optionally specify what docker image builder to use.
* Defaults to "docker"
*/
builder?: "docker" | "kaniko";

/**
* Optional arguments passed to the docker image builder
*/
builderArgs?: string[];

/**
* Path relative to base of project to build. If not provided,
* ".", i.e., the project base directory, is used.
*/
builderPath?: string;
}

const DefaultDockerOptions: DockerOptions = {
dockerImageNameCreator: DefaultDockerImageNameCreator,
dockerfileFinder: async () => "Dockerfile",
builder: "docker",
builderArgs: [],
builderPath: ".",
};

/**
* Goal that performs docker build and push depending on the provided options
*/
export class DockerBuild extends FulfillableGoalWithRegistrations<DockerOptions> {
constructor(
goalDetailsOrUniqueName: FulfillableGoalDetails | string = DefaultGoalNameGenerator.generateName(
"docker-build",
),
...dependsOn: Goal[]
) {
super(
getGoalDefinitionFrom(
goalDetailsOrUniqueName,
DefaultGoalNameGenerator.generateName("docker-build"),
DockerBuildDefinition,
),
...dependsOn,
);
}

public with(registration: DockerOptions): this {
const optsToUse = mergeOptions<DockerOptions>(DefaultDockerOptions, registration);

this.addFulfillment({
goalExecutor: executeDockerBuild(optsToUse),
name: DefaultGoalNameGenerator.generateName("docker-builder"),
progressReporter: DockerProgressReporter,
...(registration as ImplementationRegistration),
});
return this;
}
}

const DockerBuildDefinition: GoalDefinition = {
uniqueName: "docker-build",
displayName: "docker build",
environment: IndependentOfEnvironment,
workingDescription: "Running docker build",
completedDescription: "Docker build successful",
failedDescription: "Docker build failed",
isolated: true,
retryFeasible: true,
};
54 changes: 54 additions & 0 deletions lib/core/pack/docker/build/DockerProgressReporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright © 2020 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { ProgressTest, testProgressReporter } from "../../../../api-helper/goal/progress/progress";
import { ReportProgress } from "../../../../api/goal/progress/ReportProgress";

/**
* Default progress tests for our Docker builds
* @type {{test: RegExp; phase: string}[]}
*/
export const DockerProgressTests: ProgressTest[] = [
{
test: /Invoking goal hook: pre/i,
phase: "pre-hook",
},
{
test: /docker 'build'/i,
phase: "docker build",
},
{
test: /docker 'push'/i,
phase: "docker push",
},
{
test: /Invoking goal hook: post/i,
phase: "post-hook",
},
{
test: /\/kaniko\/executor/i,
phase: "kaniko build",
},
{
test: /pushed blob sha256/i,
phase: "kaniko push",
},
];

/**
* Default ReportProgress for our Docker
*/
export const DockerProgressReporter: ReportProgress = testProgressReporter(...DockerProgressTests);
Loading

0 comments on commit 79906fc

Please sign in to comment.