Несколько примеров, как Active Choices параметры можно описывать в Pipeline
Пример 1
Одиночный выбор, из предоставленного списка. Выпадающий список окружений, по умолчанию выбран первый в списке элемент.
Pipeline:
properties([ parameters([ [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select environment', filterLength: 1, filterable: false, name: 'Environment', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: 'return[\'Development\',\'Production\']' ] ] ] ]) ])
Пример 2
Одиночный выбор, на основе результата скрипта. А так же в зависимости от выбранного окружения, в параметре "Environment". Скрипт выполняет удаленную SSH команду на выбранном окружении, и возвращает список директорий находящихся в "/var/www/html" директории.
Pipeline:
properties([ parameters([ [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select Site', filterLength: 1, filterable: false, referencedParameters: 'Environment', name: 'Site', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: '''if (Environment.equals("Development")){ def command = $/ssh [email protected] sudo ls /var/www/html /$ def proc = command.execute() return proc.text.readLines() } else if(Environment.equals("Production")){ def command = $/ssh [email protected] sudo ls /var/www/html /$ def proc = command.execute() return proc.text.readLines() }''' ] ] ] ]) ])
Пример 3
Передаем в Active Choice скрипт результат предыдущего выбора, с параметра "Site". Указываем, что данный параметр зависит от двух предыдущих — "referencedParameters: 'Environment, Site'". Параметр выведет список директорий выбранного сайта, и исключит из вывода "..", чтобы пользователь не удалил случайно директорию выше указанной.
Pipeline:
properties([ parameters([ [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select Folder. \'.\' - Remove all site folder', filterLength: 1, filterable: false, referencedParameters: 'Environment, Site', name: 'Folder', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: '''if (Environment.equals("Development")){ def command = $/ssh [email protected] sudo ls -a /var/www/html'/'${Site} | grep -v '\\.\\.' /$ def proc = command.execute() return proc.text.readLines() } else if(Environment.equals("Production")){ def command = $/ssh [email protected] sudo ls -a /var/www/html'/'${Site} | grep -v '\\.\\.'/$ def proc = command.execute() return proc.text.readLines() }''' ] ] ] ]) ])
По умолчанию выбрано ".", то есть выбран весь каталог сайта.
Пример 4
Добавляем булевый параметр, для подтверждения удаления выбранной директории.
Pipeline:
properties([ parameters([ [$class: 'BooleanParameterDefinition', description: 'Set this to confirm deletion', name: 'Confirm', defaultValue: false ] ]) ])
Весь Pipeline будет выглядеть следующим образом:
Pipeline:
properties([ parameters([ [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select environment', filterLength: 1, filterable: false, name: 'Environment', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: 'return[\'Development\',\'Production\']' ] ] ], [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select Site', filterLength: 1, filterable: false, referencedParameters: 'Environment', name: 'Site', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: '''if (Environment.equals("Development")){ def command = $/ssh [email protected] sudo ls /var/www/html /$ def proc = command.execute() return proc.text.readLines() } else if(Environment.equals("Production")){ def command = $/ssh [email protected] sudo ls /var/www/html /$ def proc = command.execute() return proc.text.readLines() }''' ] ] ], [$class: 'CascadeChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Select Folder. \'.\' - Remove all site folder', filterLength: 1, filterable: false, referencedParameters: 'Environment, Site', name: 'Folder', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: '''if (Environment.equals("Development")){ def command = $/ssh [email protected] sudo ls -a /var/www/html'/'${Site} | grep -v '\\.\\.' /$ def proc = command.execute() return proc.text.readLines() } else if(Environment.equals("Production")){ def command = $/ssh [email protected] sudo ls -a /var/www/html'/'${Site} | grep -v '\\.\\.'/$ def proc = command.execute() return proc.text.readLines() }''' ] ] ], [$class: 'BooleanParameterDefinition', description: 'Set this to confirm deletion', name: 'Confirm', defaultValue: false ] ]) ])
Сам Pipeline с проверкой существования указанной директории, и уведомления в Slack, о том какой пользователь (необходим установленный плагин user build vars) какую директорию удалил, будет выглядеть следующим образом.
Pipeline:
pipeline { agent any options { buildDiscarder(logRotator(numToKeepStr: '10')) timeout(time: 60, unit:'MINUTES') timestamps() } environment { def SSH_USER = 'centos' def DEVELOPMENT_INSTANCE = '192.168.1.101' def PRODUCTION_INSTANCE = '192.168.1.102' def WEB_DIR = '/var/www/html' def SLACK_CHANNEL = 'general' } stages { stage('Definition of variables') { steps { script { if ( env.Site.isEmpty() ) { echo "Site not specified. If you continue, the www root directory may be deleted." autoCancelled = true error('Aborting the build.') } if ( env.Folder == '.' ) { env.FULL_PATH = "${WEB_DIR}/${Site}" echo "Folder not specified" echo "Path for delete is: ${FULL_PATH}" } else { env.FULL_PATH = "${WEB_DIR}/${Site}/${Folder}" echo "Path for delete is: ${FULL_PATH}" } } } } stage('Check dir existence') { steps { script { echo "Environment: ${env.Environment}" echo "Full path: ${FULL_PATH}" if ( env.Environment == 'Development' ) { env.EXIST_DIR = sh(script: 'ssh \${SSH_USER}@\${DEVELOPMENT_INSTANCE} \'[ -d \${FULL_PATH} ] && echo \"yes\" || echo \"no\"\'', returnStdout: true).trim() echo "EXIST_DIR: ${EXIST_DIR}" } else if ( env.Environment == 'Production' ) { env.EXIST_DIR = sh(script: 'ssh \${SSH_USER}@\${PRODUCTION_INSTANCE} \'[ -d \${FULL_PATH} ] && echo \"yes\" || echo \"no\"\'', returnStdout: true).trim() echo "EXIST_DIR: ${EXIST_DIR}" } else { echo "Environment not specified" autoCancelled = true error('Aborting the build.') } if ( env.EXIST_DIR == 'no' ) { echo "Directory: ${FULL_PATH} on ${env.Environment} does not exist" autoCancelled = true error('Aborting the build.') } } } } stage('Remove dir') { when { expression { return params.Confirm } } steps { script { echo "Remove directory ${FULL_PATH} on ${env.Environment} server" if ( env.Environment == 'Development' ) { sh "ssh \${SSH_USER}@\${DEVELOPMENT_INSTANCE} \"sudo rm -rf ${FULL_PATH}\"" } else if ( env.Environment == 'Production' ) { sh "ssh \${SSH_USER}@\${PRODUCTION_INSTANCE} \"sudo rm -rf ${FULL_PATH}\"" } else { echo "Environment not specified" autoCancelled = true error('Aborting the build.') } } } } stage('Output') { steps { script { wrap([$class: 'BuildUser']) { if ( env.Confirm.toBoolean() ) { echo "Directory ${FULL_PATH} on ${env.Environment} server was deleted by user: ${BUILD_USER}" slackSend channel: "${SLACK_CHANNEL}", color: 'good', message: "Job: ${JOB_NAME} was successful.\nEnvironment: `${env.Environment}`\nDirectory: `${FULL_PATH}`\nState: `Deleted`\nUser: `${BUILD_USER}`" } else { echo "Directory ${FULL_PATH} on ${env.Environment} server was deleted (Dry run) by user: ${BUILD_USER}" slackSend channel: "${SLACK_CHANNEL}", color: 'good', message: "Job: ${JOB_NAME} was successful.\nEnvironment: `${env.Environment}`\nDirectory: `${FULL_PATH}`\nState: `Dry run`\nUser: `${BUILD_USER}`" } } } } } } post { failure { slackSend channel: "${SLACK_CHANNEL}", color: 'danger', message: "Job: ${JOB_NAME} was finished with some error.\nPlease watch the Jenkins Console Output: ${JOB_URL}${BUILD_ID}/consoleFull" } aborted { slackSend channel: "${SLACK_CHANNEL}", color: 'warning', message: "Job: ${JOB_NAME} was canceled.\nPlease watch the Jenkins Console Output: ${JOB_URL}${BUILD_ID}/console." } } }