Skip to content

Commit 893fcca

Browse files
Saas-7129 runner init (#454)
1 parent b7a4de8 commit 893fcca

File tree

9 files changed

+654
-736
lines changed

9 files changed

+654
-736
lines changed

docs/docs.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const docs = require('../docs');
22

33
describe('docs generation', () => {
4-
jest.setTimeout(10000);
4+
jest.setTimeout(20000);
55
it('should generate docs', async () => {
66
await docs();
77
});

lib/interface/cli/commands/agent/install.cmd.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ const installAgentCmd = new Command({
8888
'skip-cluster-test': skipClusterTest,
8989
verbose,
9090
terminateProcess,
91-
createDemoPipeline,
92-
executeDemoPipeline,
9391
} = argv;
9492
let agent;
9593
let {
@@ -108,7 +106,7 @@ const installAgentCmd = new Command({
108106
agent = await sdk.agents.create({ name });
109107
// eslint-disable-next-line prefer-destructuring
110108
token = agent.token;
111-
console.log(`A Codefresh Runner with name: ${colors.cyan(name)} has been created.\n${colors.yellow('*IMPORTANT*')} Make sure to copy your access token now and store it in a safe location. You won’t be able to see it again.`);
109+
console.log(`A Codefresh Runner with the name: ${colors.cyan(name)} has been created.\n${colors.yellow('*IMPORTANT*')} Make sure to copy your access token now and store it in a safe location. You won’t be able to see it again.`);
112110
console.log(token);
113111
} else {
114112
// take the agent id from the token
@@ -166,7 +164,7 @@ const installAgentCmd = new Command({
166164
throw new Error(`\nRunner installation failed with code ${agentInstallStatusCode}`);
167165
}
168166
if (installRuntime) {
169-
await installRuntimeCmd.handler({
167+
return installRuntimeCmd.handler({
170168
'runtime-kube-context-name': kubeContextName,
171169
'runtime-kube-namespace': kubeNamespace,
172170
'agent-name': name,
@@ -177,8 +175,6 @@ const installAgentCmd = new Command({
177175
'skip-cluster-test': skipClusterTest,
178176
verbose,
179177
terminateProcess,
180-
createDemoPipeline,
181-
executeDemoPipeline,
182178
});
183179
}
184180
},

lib/interface/cli/commands/cluster/create.cmd.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const command = new Command({
7070
console.log('\n');
7171
}
7272
});
73-
await sdk.clusters.create({
73+
return sdk.clusters.create({
7474
contextName,
7575
context,
7676
namespace,

lib/interface/cli/commands/hybrid/init.cmd.js

Lines changed: 179 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const runnerRoot = require('../root/runner.cmd');
44
const inquirer = require('inquirer');
55
const { getAllKubeContexts, getKubeContext } = require('../../helpers/kubernetes');
66
const installAgent = require('../agent/install.cmd');
7+
const pipelinesRunCmd = require('../pipeline/run.cmd');
8+
const installMonitoring = require('../monitor/install.cmd');
79
const createContext = require('../auth/create-context.cmd');
810
const getAgents = require('../agent/get.cmd');
911
const { getConfigForSdk } = require('../../commad-line-interface');
@@ -16,8 +18,79 @@ const INSTALLATION_DEFAULTS = {
1618
NAMESPACE: 'codefresh',
1719
MAKE_DEFAULT_RE: true,
1820
RUN_DEMO_PIPELINE: true,
21+
DEMO_PIPELINE_NAME: 'Hello Codefresh',
22+
CF_CONTEXT_NAME: 'cf-runner',
1923
};
2024

25+
function prettyError(error) {
26+
try {
27+
const errMsg = _.get(error, 'message', error);
28+
let errObj = JSON.parse(errMsg);
29+
if (typeof errObj === 'string') {
30+
errObj = JSON.parse(errObj);
31+
}
32+
return _.get(errObj, 'message', error);
33+
} catch (e) {
34+
return _.get(error, 'message', JSON.stringify(error));
35+
}
36+
}
37+
38+
async function createDemoPipeline(runtimeName) {
39+
const pipeline = await sdk.pipelines.create({ metadata: { name: INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME } });
40+
pipeline.spec.runtimeEnvironment = {
41+
name: runtimeName,
42+
};
43+
pipeline.spec.steps = {};
44+
pipeline.spec.stages = ['test'];
45+
pipeline.spec.steps.test = {
46+
stage: 'test',
47+
title: 'test',
48+
image: 'ubuntu:latest',
49+
commands: ['echo hello codefresh'],
50+
};
51+
52+
await sdk.pipelines.replace(
53+
{ name: INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME },
54+
{
55+
kind: pipeline.kind,
56+
spec: pipeline.spec,
57+
metadata: pipeline.metadata,
58+
version: pipeline.version,
59+
},
60+
);
61+
}
62+
63+
async function createAndExecuteDemoPipeline(runtimeName) {
64+
let demoPipelineExists = false;
65+
66+
try {
67+
const pipelines = await sdk.pipelines.list({ id: INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME });
68+
if (_.get(pipelines, 'docs.length')) {
69+
demoPipelineExists = true;
70+
}
71+
} catch (error) {
72+
console.log(`Failed to fetch account pipelines, cause: ${error.message}`);
73+
}
74+
75+
if (!demoPipelineExists) {
76+
console.log(`Creating demo pipeline with the name: "${colors.cyan(INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME)}"`);
77+
try {
78+
await createDemoPipeline(runtimeName);
79+
} catch (error) {
80+
console.log(`${colors.red('Error: ')} Failed to create demo pipeline, cause: ${prettyError(error)}`);
81+
}
82+
} else {
83+
console.log(`Demo pipeline with the name: "${colors.cyan(INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME)}" already exists`);
84+
}
85+
86+
console.log(`${colors.yellow('*NOTE* Running a pipeline for the first time might take a longer than usual')}`);
87+
console.log(`Executing pipeline "${colors.cyan(INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME)}"`);
88+
await pipelinesRunCmd.handler({
89+
name: INSTALLATION_DEFAULTS.DEMO_PIPELINE_NAME,
90+
exitProcess: false,
91+
});
92+
}
93+
2194
const initCmd = new Command({
2295
root: false,
2396
parent: runnerRoot,
@@ -100,13 +173,14 @@ const initCmd = new Command({
100173
'skip-version-check': skipVersionCheck,
101174
yes: noQuestions,
102175
verbose,
103-
name, token, url,
176+
name, url,
104177
} = argv;
105178
let {
106179
'kube-context-name': kubeContextName,
107180
'kube-namespace': kubeNamespace,
108181
'set-default-runtime': shouldMakeDefaultRe,
109182
'exec-demo-pipeline': shouldExecutePipeline,
183+
token,
110184
} = argv;
111185

112186
if (_.get(sdk, 'config.context.isNoAuth') && !token) {
@@ -123,98 +197,126 @@ const initCmd = new Command({
123197
kubeNamespace = INSTALLATION_DEFAULTS.NAMESPACE;
124198
shouldMakeDefaultRe = INSTALLATION_DEFAULTS.MAKE_DEFAULT_RE;
125199
shouldExecutePipeline = INSTALLATION_DEFAULTS.RUN_DEMO_PIPELINE;
126-
}
200+
} else {
201+
const questions = [];
202+
if (!kubeContextName && !noQuestions) {
203+
const contexts = getAllKubeContexts(kubeConfigPath);
204+
const currentKubeContext = getKubeContext(kubeConfigPath);
127205

128-
const questions = [];
129-
if (!kubeContextName && !noQuestions) {
130-
const contexts = getAllKubeContexts(kubeConfigPath);
131-
const currentKubeContext = getKubeContext(kubeConfigPath);
132-
133-
questions.push({
134-
type: 'list',
135-
name: 'context',
136-
message: 'Name of Kubernetes context to use',
137-
default: currentKubeContext,
138-
choices: contexts,
139-
});
140-
}
141-
if (!kubeNamespace && !noQuestions) {
142-
questions.push({
143-
type: 'input',
144-
name: 'namespace',
145-
default: INSTALLATION_DEFAULTS.NAMESPACE,
146-
message: 'Kubernetes namespace to install into (will be created if it does not exist)',
147-
validate: value => (value !== undefined && value !== '') || 'Please enter namespace\'s name',
148-
});
149-
}
206+
questions.push({
207+
type: 'list',
208+
name: 'context',
209+
message: 'Name of Kubernetes context to use',
210+
default: currentKubeContext,
211+
choices: contexts,
212+
});
213+
}
214+
if (!kubeNamespace && !noQuestions) {
215+
questions.push({
216+
type: 'input',
217+
name: 'namespace',
218+
default: INSTALLATION_DEFAULTS.NAMESPACE,
219+
message: 'Kubernetes namespace to install into (will be created if it does not exist)',
220+
validate: value => (value !== undefined && value !== '') || 'Please enter namespace\'s name',
221+
});
222+
}
150223

151-
if (_.isUndefined(shouldMakeDefaultRe) && !noQuestions) {
152-
questions.push({
153-
type: 'confirm',
154-
name: 'shouldMakeDefaultRe',
155-
default: INSTALLATION_DEFAULTS.MAKE_DEFAULT_RE,
156-
message: 'Set this as the default runtime environment for your Codefresh account? (Y/N)',
157-
});
158-
}
224+
if (_.isUndefined(shouldMakeDefaultRe) && !noQuestions) {
225+
questions.push({
226+
type: 'confirm',
227+
name: 'shouldMakeDefaultRe',
228+
default: INSTALLATION_DEFAULTS.MAKE_DEFAULT_RE,
229+
message: 'Set this as the default runtime environment for your Codefresh account? (Y/N)',
230+
});
231+
}
159232

160-
if (_.isUndefined(shouldExecutePipeline) && !noQuestions) {
161-
questions.push({
162-
type: 'confirm',
163-
name: 'shouldExecutePipeline',
164-
default: INSTALLATION_DEFAULTS.RUN_DEMO_PIPELINE,
165-
message: 'Run demo pipeline after install? (Y/N)',
166-
});
167-
}
233+
if (_.isUndefined(shouldExecutePipeline) && !noQuestions) {
234+
questions.push({
235+
type: 'confirm',
236+
name: 'shouldExecutePipeline',
237+
default: INSTALLATION_DEFAULTS.RUN_DEMO_PIPELINE,
238+
message: 'Run demo pipeline after install? (Y/N)',
239+
});
240+
}
168241

169-
console.log(colors.green('This installer will guide you through the Codefresh Runner installation process'));
170-
const answers = await inquirer.prompt(questions);
171-
kubeContextName = kubeContextName || answers.context;
172-
kubeNamespace = kubeNamespace || answers.namespace;
173-
shouldMakeDefaultRe = shouldMakeDefaultRe || answers.shouldMakeDefaultRe;
174-
shouldExecutePipeline = shouldExecutePipeline || answers.shouldExecutePipeline;
242+
console.log(colors.green('This installer will guide you through the Codefresh Runner installation process'));
243+
const answers = await inquirer.prompt(questions);
244+
kubeContextName = kubeContextName || answers.context;
245+
kubeNamespace = kubeNamespace || answers.namespace;
246+
shouldMakeDefaultRe = shouldMakeDefaultRe || answers.shouldMakeDefaultRe;
247+
shouldExecutePipeline = shouldExecutePipeline || answers.shouldExecutePipeline;
248+
}
175249

176-
console.log(colors.green(`\nInstallation options summary:
177-
${colors.white('1. Kubernetes Context:')} ${colors.cyan(kubeContextName)}
178-
${colors.white('2. Kubernetes Namespace:')} ${colors.cyan(kubeNamespace)}
179-
${colors.white('3. Set this as default account runtime-environment:')} ${colors.cyan(shouldMakeDefaultRe)}
180-
${colors.white('4. Execute demo pipeline after install:')} ${colors.cyan(shouldExecutePipeline)}
181-
`));
250+
console.log(`\n${colors.green('Installation options summary:')}
251+
1. Kubernetes Context: ${colors.cyan(kubeContextName)}
252+
2. Kubernetes Namespace: ${colors.cyan(kubeNamespace)}
253+
3. Set this as default account runtime-environment: ${colors.cyan(shouldMakeDefaultRe)}
254+
4. Execute demo pipeline after install: ${colors.cyan(shouldExecutePipeline)}
255+
`);
182256

183257
if (token) { // Add context
184-
await createContext.handler({
185-
apiKey: token,
186-
name: 'cf-runner',
187-
url,
188-
});
189-
const config = await getConfigForSdk();
190-
await sdk.configure(config);
191-
console.log('A Codefresh context named "cf-runner" was added to your "cfconfig" file.');
258+
try {
259+
await createContext.handler({
260+
apiKey: token,
261+
name: INSTALLATION_DEFAULTS.CF_CONTEXT_NAME,
262+
url,
263+
});
264+
const config = await getConfigForSdk();
265+
await sdk.configure(config);
266+
console.log(`A Codefresh context named '${INSTALLATION_DEFAULTS.CF_CONTEXT_NAME}' was added to your "cfconfig" file.`);
267+
} catch (error) {
268+
console.log(`${colors.red('Error:')} Could not use the provided token, failed with error: ${prettyError(error)}`);
269+
process.exit(1);
270+
}
271+
} else {
272+
token = _.get(sdk, 'config.context.token');
192273
}
193274

194275
// Install runner and runtime
195-
await installAgent.handler({
196-
name,
276+
let runtimeName;
277+
try {
278+
runtimeName = await installAgent.handler({
279+
name,
280+
'kube-context-name': kubeContextName,
281+
'kube-node-selector': kubeNodeSelector,
282+
'dry-run': dryRun,
283+
'in-cluster': inCluster,
284+
'kube-namespace': kubeNamespace,
285+
'kubernetes-runner-type': kubernetesRunnerType,
286+
tolerations,
287+
'venona-version': venonaVersion,
288+
'kube-config-path': kubeConfigPath,
289+
'skip-version-check': skipVersionCheck,
290+
'install-runtime': true,
291+
verbose,
292+
'make-default-runtime': shouldMakeDefaultRe,
293+
terminateProcess: false,
294+
});
295+
} catch (error) {
296+
console.log(`${colors.red('Error: ')} Runner installation failed with error: ${prettyError(error)}`);
297+
process.exit(1);
298+
}
299+
300+
// Install monitoring
301+
await installMonitoring.handler({
302+
'kube-config-path': kubeConfigPath,
303+
'cluster-id': kubeContextName,
197304
'kube-context-name': kubeContextName,
198-
'kube-node-selector': kubeNodeSelector,
199-
'dry-run': dryRun,
200-
'in-cluster': inCluster,
201305
'kube-namespace': kubeNamespace,
202-
'kubernetes-runner-type': kubernetesRunnerType,
203-
tolerations,
204-
'venona-version': venonaVersion,
205-
'kube-config-path': kubeConfigPath,
206-
'skip-version-check': skipVersionCheck,
207-
'install-runtime': true,
306+
token,
208307
verbose,
209-
'make-default-runtime': shouldMakeDefaultRe,
210-
terminateProcess: false,
211-
createDemoPipeline: true,
212-
executeDemoPipeline: shouldExecutePipeline,
308+
noExit: true, // to prevent if from calling: process.exit()
213309
});
214-
console.log(colors.green('Runner Status:\n'));
310+
311+
// Post Installation
312+
if (shouldExecutePipeline) {
313+
await createAndExecuteDemoPipeline(runtimeName);
314+
}
315+
316+
console.log(colors.green('\nRunner Status:'));
215317
await getAgents.handler({});
216318
console.log(colors.green(`\nDocumenation link: ${colors.blue('https://codefresh.io/docs/docs/enterprise/codefresh-runner/#codefresh-runner-preview-release')}`));
217-
console.log(colors.green(`\nIf you had any issues with the installation please report them at: ${colors.blue('https://github.com/codefresh-io/cli/issues/new')}`));
319+
console.log(colors.green(`If you had any issues with the installation please report them at: ${colors.blue('https://github.com/codefresh-io/cli/issues/new')}`));
218320
process.exit(); // TODO : This is not needed - needed to be fixed
219321
},
220322
});

lib/interface/cli/commands/monitor/install.cmd.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const installMonitorCmd = new Command({
4444
'kube-context-name': kubeContextName,
4545
'kube-namespace': kubeNamespace,
4646
verbose,
47+
noExit,
4748
} = argv;
4849
const apiHost = sdk.config.context.url;
4950
const events = new ProgressEvents();
@@ -73,9 +74,12 @@ const installMonitorCmd = new Command({
7374
events,
7475
});
7576
if (monitorInstallStatusCode !== 0) {
76-
throw new Error(`\nAgent installation failed with code ${monitorInstallStatusCode}`);
77+
throw new Error(`\nCodefresh Monitoring installation failed with code ${monitorInstallStatusCode}`);
78+
}
79+
80+
if (!noExit) {
81+
process.exit(0);
7782
}
78-
process.exit(0);
7983
},
8084
});
8185

0 commit comments

Comments
 (0)