Jenkins Pipeline sshPublisher: How to get exit code and output of execCommand? - jenkins

Using Jenkins Pipeline's sshPublisher plugin ("publish over ssh"), is it possible to get the exit code and output of the command ran with execCommand (after artifacts have been transferred over)?
I'm using the plugin as follows:
script {
echo "Sending artifacts to machine at " + remoteDirectory
// Use of the ssh publisher plugin over SSH
sshPublisher(
failOnError: false,
publishers: [
sshPublisherDesc(
configName: "my-drive",
transfers: [
sshTransfer(
sourceFiles: mySourceFilesList,
remoteDirectory: remoteDirectory,
flatten: true,
execCommand: commandToExec,
execTimeout: 1800000
)
],
sshRetry: [
retries: 0
]
)
]
)
// How can I get the output of execCommand?
// If the exit code was 1, I want to perform some special steps
// I'd also like to include the output of the command in these steps
}
The wiki page here says (this is old and from 2011 though):
STDOUT and STDERR from the command execution are recorded in the
Jenkins console.

It is a "No" (can't be sure, but I try every thing I can).
And now I'm happy with this script ssh user#nas01 su -c "/path/to/command1 arg1 arg2"

Related

Jenkins Pipeline: No Such DSL Method ‘perfReport’ found

I am getting the error No such Dsl method ‘perfReport’ found
post {
always
// sh '1s -ltr target/jmeter/reports*
sh sh
mkdir -p target/jmeter_results/*
sh
"cp -a target/jmeter/reports/*/* target/imeter results/"
sh
'op -a target/jmeter/results/*.cav target/jmeter_results/results.txt*
"ep -a target/jmeter/logs/*.log target/jmeter_results/Jmeter.jmx.log* sh
'ls -ltr target/imeter results/' archiveArtifacts artifacts: 'target/imeter results/*, allowEmptyArchive: true, fingerprint: true, caseSensitive: true, onlyIf
publishHTML (target: [allowMissing: false, alwayslinkToLastBuild: true, keepAll: false, reportDir: "target/imeter results/. reportFiles:
index.html'
reportName:
"Performance Test Result*
//reportTitles:
])
perfReport errorFailedThreshold: 5, errorUnstableResponseTimeThreshold: 'results.txt:1000*, errorUnstableThreshold: 2, excludeRespe
changed {
notifybuildstatus (currentBuild.currentResult)
def notifybuildstatus (buildstatus)
def status
switch (buildStatus) {
case SUCCESS' :
status = ' GREEN*
break
case 'UNSTABLE*:
status = 'AMBER*
break
case FAILURE::
status break
"RED*
This error can mean:
The performance plugin isn't installed on your jenkins. This post explains how you can see which plugins are installed.
You have a typo, and a property name is wrong, or the type of the value different than the expexted, e.g. the plugin expects a bool but you're passing a string.
From your code, the value of errorUnstableResponseTimeThreshold has an asterisk (*) instead of the closing quote ('). That may be the cause. The command is truncated so it's hard to say if the other keys have valid values.
You can try using the pipeline snippet generator to ensure your syntax is correct, but I'm not sure if it's supported for this plugin.

AWS CDK Pipeline: Assets stage fails to find buildSpec FileAsset.yaml when publishAssetsInParallel is disabled

We are trying to get our multi-stack application deployed using the cdk pipeline library.
We have recently disabled the publishAssetsInParallel flag, as with the default setting our pipeline would create >20 FileAsset objects under the Assets stage, which AWS then complains as being too many CodeBuild projects running parallel.
However, with this property now disabled, I'm getting the following error for the Assets stage:
[Container] 2022/11/14 12:04:24 Phase complete: DOWNLOAD_SOURCE State: FAILED
[Container] 2022/11/14 12:04:24 Phase context status code: YAML_FILE_ERROR Message: stat /codebuild/output/src112668013/src/buildspec-c866864112c35d54804951dbe96b99440c9b891fde-FileAsset.yaml: no such file or directory
I'm assuming this is supposed to be a build spec that is create by cdk pipeline, as we didn't need to create a build spec when things were running in parallel.
Here is the current pipeline code:
const pipeline = new CodePipeline(this, 'Pipeline', {
publishAssetsInParallel: false,
selfMutation: false,
pipelineName: fullStackName('Pipeline', app),
synth: new CodeBuildStep('SynthStep', {
input: CodePipelineSource.codeCommit(repo, repoBranchName, {codeBuildCloneOutput: true}),
buildEnvironment: {computeType: ComputeType.MEDIUM},
installCommands: [
'npm install -g yarn',
'yarn install',
'cd apps/cloud-app',
'yarn install',
'yarn global add aws-cdk'
],
commands: [
'yarn build',
'cdk synth'
],
primaryOutputDirectory: 'apps/cloud-app/cdk.out'
}
)
});
UPDATE:
I reverted the publishAssetsInParallel flag to its default setting to compare, and it seems there is a fundamental difference in the way it creates the FileAsset CodeBuild projects based on this flag. With it enabled, when I inspect the build details for one of the FileAsset projects that is created, I can see under the buildspec section it contains a concrete implementation of a build spec, eg:
{
"version": "0.2",
"phases": {
"install": {
"commands": [
"npm install -g cdk-assets#2"
]
},
"build": {
"commands": [
"cdk-assets --path \"MyStack.assets.json\" --verbose publish \"2357296280127ce793d8dbb13e6c907db22f5dcc57a173ba77fcd19a76d8f444:12345678910-eu-west-2\""
]
}
}
}
With the flag disabled, the buildspec simply contains a pointer to a buildspec file as below, which it then fails to find...
buildspec-c866864112c35d54804951dbe96b99440c9b891fde-FileAsset.yaml
Self-mutation has to be enabled - currently, asset updates mutate the pipeline.
Reference: https://github.com/aws/aws-cdk/issues/9080

Problem when generating JUnit report on Jenkins Pipeline

I'm creating a post job on Jenkins pipeline to publish test results using junit, html and cobertura. The code looks like this
post {
always {
publishTestResults(
script: this,
junit: [
active:true,
allowEmptyResults:true,
archive: true,
pattern: '**/reports/mocha.xml',
updateResults: true
],
cobertura: [
active:true,
allowEmptyResults:true,
archive:true,
pattern: '**/coverage/cobertura/cobertura-coverage.xml'
],
html: [
active:true,
allowEmptyResults:true,
archive:true,
name: 'NYC/Mocha',
path: '**/coverage/html'
],
lcov: [
active:true,
allowEmptyResults:true,
archive:true,
name: 'LCOV Coverage',
path: '**/coverage/lcov/lcov-report'
]
)
cobertura coberturaReportFile: 'coverage/cobertura/cobertura-coverage.xml'
junit 'reports/mocha.xml'
cleanWs()
// deleteDir()
script {
FAILED_STAGE = env.STAGE_NAME
}
}
}
}
The problem is when I execute the job on Jenkins I receive an error message:
find . -wholename **/reports/mocha.xml -exec touch {} ;
touch: cannot touch './reports/mocha.xml': Permission denied
I suppose the issue raised by junit command. How could I solve this problem?
P/S: Jenkins server runs on Ubuntu. I tried to modify /etc/sudoers and add this line to make Jenkins executes command as root. It still could not solve my problem.
jenkins ALL=(ALL) NOPASSWD: ALL
From checking the code at: https://github.com/SAP/jenkins-library/blob/5c13a0e2a20132336824c70b743c364bcb5341f4/vars/testsPublishResults.groovy#L136
Looks like you can avoid the issue by setting updateResults to false
If you absolutely have to update the timestamp on the result file, you'll have to open a terminal session, go to the project workspace (with jenkins user) and try to run touch ./reports/mocha.xml and then debug it from there.

How to use publish over ssh plugin in pipeline

I would like to SSH to linux server from Jenkins hosted on windows and execute a command over in linux machine, I tried installing publish over ssh plugin and tested the connection in global config and it works fine, I don't know how to proceed next in pipeline. Any help would be appreciated.
If you are using a pipeline project and a Jenkinsfile, then all you need to do is go into your project in Jenkins and click configure. In the pipeline section of the configuration, at the bottom there is a link "pipeline syntax". It will take you to the Snippet Generator. Its self explanatory and in our case it allows to generate "publish over ssh" snippets that you would add to your Jenkinsfile (add it to a steps section inside a stage definition). In the generator you can define what to publish, options to run a shell command, etc. source
In case you were looking for the syntax for a declarative pipeline (Jenkinsfile) for Publish-Over-SSH, (Instead of the scripted pipeline, which is all I could find). Here's what finally worked for me.
pipeline{
agent any
environment {
RELEASENAME="yourProject-ci"
}
stages{
stage("Get the charts..."){
steps {checkout scm}
}
stage('SSH transfer') {
steps([$class: 'BapSshPromotionPublisherPlugin']) {
sshPublisher(
continueOnError: false, failOnError: true,
publishers: [
sshPublisherDesc(
configName: "kubernetes_master",
verbose: true,
transfers: [
sshTransfer(execCommand: "/bin/rm -rf /opt/deploy/helm"),
sshTransfer(sourceFiles: "helm/**",)
]
)
]
)
}
}
stage('Deploy Helm Scripts'){
steps([$class: 'BapSshPromotionPublisherPlugin']) {
sshPublisher(
continueOnError: false, failOnError: true,
publishers: [
sshPublisherDesc(
configName: "kubernetes_master",
verbose: true,
transfers: [
sshTransfer(execCommand: "cd /opt/deploy/helm;helm upgrade ${RELEASENAME} . --install"),
]
)
]
)
}
}
}
}
I have a checkout that happens first and then I copy some helm charts from the checkout to my kubernetes master and then run the charts.
configName: "kubernetes_master" is something I setup in the Publish_over_ssh plugin configuration section (Found under Manage Jenkins > Configure System) so I could reference it. It includes a username, sshkey, destination hostname, and base directory for the destination which I put as /opt/deploy.
FYI execCommand does not use the base directory... it assumes you will use full pathing.
Hope that helps.
edit: I should probably mention that there are lots more options for the sshPublisher than what I used. You can find them here: https://jenkins.io/doc/pipeline/steps/publish-over-ssh/
Based on levis answer, the below has worked for me.
stage('Deploy') {
agent any
steps {
sh 'mv target/my-app-0.0.1-SNAPSHOT.jar my-app.jar'
sshPublisher(
continueOnError: false,
failOnError: true,
publishers: [
sshPublisherDesc(
configName: "my-ssh-connection",
transfers: [sshTransfer(sourceFiles: 'my-app.jar')],
verbose: true
)
]
)
}
}
I got this question some time ago, and here is the answer. Change the code according to your requirement.
pipeline {
agent any
options { timestamps () }
stages {
stage('Publish over ssh plugin in pipeline') {
steps([$class: 'BapSshPromotionPublisherPlugin']) {
script {
List SERVERS_LIST = ["Server_1", "Server_2"]
for(cr_server in SERVERS_LIST){
sshPublisher(
publishers: [
sshPublisherDesc(
configName: cr_server,
transfers: [
sshTransfer(
cleanRemote: false,
excludes: '',
execCommand: '',
execTimeout: 120000,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '',
remoteDirectorySDF: false,
removePrefix: '',
sourceFiles: '**/*'
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: false
)
]
)
}
}
}
}
}
}
I don't know how helpful this'll be but I found a tutorial on something that should work until they have a nicer way to do it.

How do I make xunit stop the jenkins pipeline on fail?

This guy seems to have the same problem.
Here is what I am doing:
stage('Test') {
steps {
bat "\"${tool 'VSTestRunner'}\" %WORKSPACE%\\MyApp\\bin\\Debug\\MyApp.dll /logger:trx & exit 0"
// The test publish is responsible for decided whether the test stage failed
step([$class : 'XUnitPublisher',
testTimeMargin: '3000',
thresholdMode: 1,
thresholds: [
[$class: 'FailedThreshold', failureNewThreshold: '', failureThreshold: '1', unstableNewThreshold: '', unstableThreshold: ''],
[$class: 'SkippedThreshold', failureNewThreshold: '', failureThreshold: '', unstableNewThreshold: '', unstableThreshold: '']
],
tools : [[$class: 'MSTestJunitHudsonTestType',
deleteOutputFiles: true,
failIfNotNew: false,
pattern: "TestResults\\*.trx",
skipNoTestFiles: false,
stopProcessingIfError: true
]]
])
}
}
If the tests fail the pipeline still continues.
I would like to be able to control whether the pipeline continues or not via the xunit settings. Is there a more elegant way of doing this than this:
if (currentBuild.result.equals("FAILURE")) {
throw "Test results did not pass thresholds"
}
Also, what does "stopProcessingIfError" do? I thought it would stop the pipeline if the error threshold was exceeded but it doesn't. Is there a param to the xunit service that does that?
FAILED, SUCCESS, and UNSTABLE are jenkins build status and not exit status. exit status should come from the process that is being executed. So, your solution is to set an exit 1 (or something non-zero), if the test fails. You batch step seem to be setting an exit 0. Check for the ERRORLEVEL as you seem to be in windows, and if its non-zero, break out from the pipeline by forcing an `exit 1'
note: it can be anything but should not be 0. (i am referring to the 1 in exit code)

Resources