@atomist/sdm-core
Version:
Atomist Software Delivery Machine - Implementation
192 lines • 9.54 kB
JavaScript
/*
* Copyright © 2019 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.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const sdm_1 = require("@atomist/sdm");
const _ = require("lodash");
const FulfillGoalOnRequested_1 = require("../../handlers/events/delivery/goals/FulfillGoalOnRequested");
const goalExecution_1 = require("../../handlers/events/delivery/goals/goalExecution");
const CacheCleanupAutomationEventListener_1 = require("../../handlers/events/delivery/goals/k8s/CacheCleanupAutomationEventListener");
const defaultSoftwareDeliveryMachineConfiguration_1 = require("../../machine/defaultSoftwareDeliveryMachineConfiguration");
const array_1 = require("../../util/misc/array");
const goalSigning_1 = require("../signing/goalSigning");
const SdmGoalMetricReportingAutomationEventListener_1 = require("../util/SdmGoalMetricReportingAutomationEventListener");
const startupMessage_1 = require("../util/startupMessage");
const InvokeSdmStartupListenersAutomationEventListener_1 = require("./InvokeSdmStartupListenersAutomationEventListener");
const modes_1 = require("./modes");
/**
* Configure and set up a Software Delivery Machine instance with the automation-client framework for standalone
* or single goal based execution
* @param {(configuration: (Configuration & SoftwareDeliveryMachineOptions)) => SoftwareDeliveryMachine} machineMaker
* @param {ConfigureOptions} options
* @returns {ConfigurationPostProcessor}
*/
function configureSdm(machineMaker, options = {}) {
return (config) => __awaiter(this, void 0, void 0, function* () {
let mergedConfig = config;
// Configure the local SDM
mergedConfig = (yield doWithSdmLocal(local => {
return local.configureLocal()(mergedConfig);
})) || mergedConfig;
const defaultSdmConfiguration = defaultSoftwareDeliveryMachineConfiguration_1.defaultSoftwareDeliveryMachineConfiguration(config);
mergedConfig = _.merge(defaultSdmConfiguration, mergedConfig);
sdm_1.validateConfigurationValues(mergedConfig, options);
const sdm = yield machineMaker(mergedConfig);
yield doWithSdmLocal(local => sdm.addExtensionPacks(local.LocalLifecycle, local.LocalSdmConfig));
// Configure the job forking ability
yield configureJobLaunching(mergedConfig, sdm);
configureGoalSigning(mergedConfig);
yield registerMetadata(mergedConfig, sdm);
// Register startup message detail
_.update(mergedConfig, "logging.banner.contributors", old => !!old ? old : []);
mergedConfig.logging.banner.contributors.push(startupMessage_1.sdmStartupMessage(sdm), startupMessage_1.sdmExtensionPackStartupMessage(sdm));
_.update(mergedConfig, "listeners", old => !!old ? old : []);
mergedConfig.listeners.push(new InvokeSdmStartupListenersAutomationEventListener_1.InvokeSdmStartupListenersAutomationEventListener(sdm), new SdmGoalMetricReportingAutomationEventListener_1.SdmGoalMetricReportingAutomationEventListener());
return mergedConfig;
});
}
exports.configureSdm = configureSdm;
/**
* Configure how this SDM is going to handle goals
* @param mergedConfig
* @param machine
*/
function configureJobLaunching(mergedConfig, machine) {
return __awaiter(this, void 0, void 0, function* () {
const forked = process.env.ATOMIST_ISOLATED_GOAL === "true";
if (forked) {
configureSdmToRunExactlyOneGoal(mergedConfig, machine);
}
else {
// initialize the GoalSchedulers
for (const goalScheduler of array_1.toArray(mergedConfig.sdm.goalScheduler || [])) {
if (!!goalScheduler.initialize) {
yield goalScheduler.initialize(mergedConfig);
}
}
_.update(mergedConfig, "commands", old => !!old ? old : []);
mergedConfig.commands.push(...machine.commandHandlers);
_.update(mergedConfig, "events", old => !!old ? old : []);
mergedConfig.events.push(...machine.eventHandlers);
_.update(mergedConfig, "ingesters", old => !!old ? old : []);
mergedConfig.ingesters.push(...machine.ingesters);
}
});
}
/**
* Configure SDM to run only one goal
* @param mergedConfig
* @param sdm
*/
function configureSdmToRunExactlyOneGoal(mergedConfig, sdm) {
if (process.env.ATOMIST_JOB_NAME) {
mergedConfig.name = process.env.ATOMIST_REGISTRATION_NAME;
}
else {
mergedConfig.name = `${mergedConfig.name}-${process.env.ATOMIST_GOAL_ID || automation_client_1.guid()}`;
}
// Force ephemeral policy and no handlers or ingesters
mergedConfig.policy = "ephemeral";
mergedConfig.commands = [];
mergedConfig.events = [
() => new FulfillGoalOnRequested_1.FulfillGoalOnRequested(sdm.goalFulfillmentMapper, [...sdm.goalExecutionListeners])
];
mergedConfig.ingesters = [];
mergedConfig.ws.enabled = false;
mergedConfig.cluster.enabled = false;
mergedConfig.listeners.push(new goalExecution_1.GoalExecutionAutomationEventListener(sdm), new CacheCleanupAutomationEventListener_1.CacheCleanupAutomationEventListener(sdm));
mergedConfig.requestProcessorFactory =
(automations, cfg, listeners) => new goalExecution_1.GoalExecutionRequestProcessor(automations, cfg, listeners);
// Disable app events for forked clients
mergedConfig.applicationEvents.enabled = false;
}
/**
* Configure SDM to sign and verify goals
* @param mergedConfig
*/
function configureGoalSigning(mergedConfig) {
if (!!mergedConfig.sdm.goalSigning && mergedConfig.sdm.goalSigning.enabled === true) {
_.update(mergedConfig, "graphql.listeners", old => !!old ? old : []);
mergedConfig.graphql.listeners.push(new goalSigning_1.GoalSigningAutomationEventListener(mergedConfig.sdm.goalSigning));
}
}
function registerMetadata(config, machine) {
return __awaiter(this, void 0, void 0, function* () {
// tslint:disable-next-line:no-implicit-dependencies
const sdmPj = require("@atomist/sdm/package.json");
// tslint:disable-next-line:no-implicit-dependencies
const sdmCorePj = require("@atomist/sdm-core/package.json");
config.metadata = Object.assign(Object.assign({}, config.metadata), { "atomist.sdm": `${sdmPj.name}:${sdmPj.version}`, "atomist.sdm-core": `${sdmCorePj.name}:${sdmCorePj.version}`, "atomist.sdm.name": machine.name, "atomist.sdm.extension-packs": machine.extensionPacks.map(ex => `${ex.name}:${ex.version}`).join(", ") });
config.sdm.name = machine.name;
yield doWithSdmLocal(() => {
// tslint:disable-next-line:no-implicit-dependencies
const sdmLocalPj = require("@atomist/sdm-local/package.json");
config.metadata["atomist.sdm-local"] = `${sdmLocalPj.name}:${sdmLocalPj.version}`;
});
});
}
/**
* Perform the given operation with the sdm-local module if it's available.
* If it isn't, silently continue without error.
* @param {(sdmLocal: any) => any} callback
* @return {any}
*/
function doWithSdmLocal(callback) {
return __awaiter(this, void 0, void 0, function* () {
if (modes_1.isInLocalMode() || modes_1.isGitHubAction()) {
// tslint:disable-next-line:no-implicit-dependencies
const local = attemptToRequire("@atomist/sdm-local", !process.env.ATOMIST_NPM_LOCAL_LINK);
if (local) {
return callback(local);
}
else {
automation_client_1.logger.warn("Skipping local mode configuration because 'ATOMIST_NPM_LOCAL_LINK' was defined, " +
"but '@atomist/sdm-local' could not be loaded");
return undefined;
}
}
return undefined;
});
}
/**
* Attempt to NPM require module
* @param module
* @param failOnError
*/
function attemptToRequire(module, failOnError) {
try {
return require(module);
}
catch (err) {
if (failOnError) {
throw new Error(`Unable to load '${module}'. Please install with 'npm install ${module}'.`);
}
else {
return undefined;
}
}
}
//# sourceMappingURL=configureSdm.js.map
;