diff --git a/jenkins_pipelines/environments/common/pipeline-aws.groovy b/jenkins_pipelines/environments/common/pipeline-aws.groovy index 5c999c72d..bf1c1ae1f 100644 --- a/jenkins_pipelines/environments/common/pipeline-aws.groovy +++ b/jenkins_pipelines/environments/common/pipeline-aws.groovy @@ -3,37 +3,33 @@ def run(params) { deployed = false env.resultdir = "${WORKSPACE}/results" env.resultdirbuild = "${resultdir}/${BUILD_NUMBER}" + // The junit plugin doesn't affect full paths junit_resultdir = "results/${BUILD_NUMBER}/results_junit" local_mirror_dir = "${resultdir}/sumaform-local" aws_mirror_dir = "${resultdir}/sumaform-aws" awscli = '/usr/local/bin/aws' - suma43_build_url = "https://dist.suse.de/ibs/SUSE:/SLE-15-SP4:/Update:/Products:/Manager43/images/" node_user = 'jenkins' - build_validation = true ssh_option = '-o StrictHostKeyChecking=no -o ConnectTimeout=7200 -o ServerAliveInterval=60' server_ami = null proxy_ami = null + url_build_image = "https://download.suse.de/ibs/Devel:/PubCloud:/Stable:/CrossCloud:/SLE15-SP5/images/" //Deployment variables deployed_local = false deployed_aws = false - // Declare lock resource use during node bootstrap - mgrCreateBootstrapRepo = 'share resource to avoid running mgr create bootstrap repo in parallel' - def client_stage_result_fail = false - local_mirror_params = "--outputdir ${resultdir} --tf susemanager-ci/terracumber_config/tf_files/local_mirror.tf --gitfolder ${local_mirror_dir}" aws_mirror_params = "--outputdir ${resultdir} --tf susemanager-ci/terracumber_config/tf_files/aws_mirror.tf --gitfolder ${aws_mirror_dir}" env.common_params = "--outputdir ${resultdir} --tf susemanager-ci/terracumber_config/tf_files/${params.tf_file} --gitfolder ${aws_mirror_dir} --bastion_ssh_key ${params.key_file}" + env.exports = "export BUILD_NUMBER=${BUILD_NUMBER}; export CAPYBARA_TIMEOUT=${capybara_timeout}; export DEFAULT_TIMEOUT=${default_timeout}; " - //Capybara configuration - def capybara_timeout =30 - def default_timeout = 300 + // Upload image variables + security_group_id = 'sg-0778949b97990ce04' + subnet_id = 'subnet-05b9d049f3af01c38' + image_help_ami = 'ami-0fd8993005af51cc4' - // Path to JSON run set file for non MU repositories - env.non_MU_channels_tasks_file = 'susemanager-ci/jenkins_pipelines/data/non_MU_channels_tasks.json' if (params.terraform_parallelism) { @@ -43,9 +39,46 @@ def run(params) { } // Public IP for AWS ingress String[] ALLOWED_IPS = params.allowed_IPS.split("\n") + if (params.bastion_ssh_key_file) { + env.common_params = "${env.common_params} --bastion_ssh_key ${params.bastion_ssh_key_file} --bastion_user ${params.bastion_username}" + if (params.bastion_hostname) { + env.common_params = "${env.common_params} --bastion_hostname ${params.bastion_hostname}" + } + } + + def previous_commit = null + def product_commit = null + if (params.show_product_changes) { + // Retrieve the hash commit of the last product built in OBS/IBS and previous job + def prefix = env.JOB_BASE_NAME.split('-acceptance-tests')[0] + if (prefix == "uyuni-master-dev") { + prefix = "manager-Head-dev" + } + // The 2obs jobs are releng, not dev + prefix = prefix.replaceAll("-dev", "-releng") + def request = httpRequest "https://ci.suse.de/job/${prefix}-2obs/lastBuild/api/json" + def requestJson = readJSON text: request.getContent() + product_commit = "${requestJson.actions.lastBuiltRevision.SHA1}" + product_commit = product_commit.substring(product_commit.indexOf('[') + 1, product_commit.indexOf(']')); + print "Current product commit: ${product_commit}" + previous_commit = currentBuild.getPreviousBuild().description + if (previous_commit == null) { + previous_commit = product_commit + } else { + previous_commit = previous_commit.substring(previous_commit.indexOf('[') + 1, previous_commit.indexOf(']')); + } + print "Previous product commit: ${previous_commit}" + } + // Start pipeline + deployed = false try { stage('Clone terracumber, susemanager-ci and sumaform') { + if (params.show_product_changes) { + // Rename build using product commit hash + currentBuild.description = "[${product_commit}]" + } + // Create a directory for to place the directory with the build results (if it does not exist) sh "mkdir -p ${resultdir}" git url: params.terracumber_gitrepo, branch: params.terracumber_ref @@ -53,58 +86,55 @@ def run(params) { checkout scm } // Clone sumaform for aws and local repositories - sh "./terracumber-cli ${local_mirror_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync --sumaform-backend libvirt" - sh "./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync --sumaform-backend aws" + sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${local_mirror_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync" + sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync --sumaform-backend aws" } - - if (params.prepare_aws_env) { stage("Prepare AWS environment") { parallel( "upload_latest_image": { - if (params.use_latest_ami_image) { - stage('Clean old images') { - // Get all image ami ids - image_amis = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=SUSE-Manager-*-BYOS*' --region ${params.aws_region} | jq -r '.Images[].ImageId'", - returnStdout: true) - // Get all snapshot ids - image_snapshots = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=SUSE-Manager-*-BYOS*' --region ${params.aws_region} | jq -r '.Images[].BlockDeviceMappings[0].Ebs.SnapshotId'", - returnStdout: true) - - String[] ami_list = image_amis.split("\n") - String[] snapshot_list = image_snapshots.split("\n") - - // Deregister all BYOS images - ami_list.each { ami -> - if (ami) { - sh(script: "${awscli} ec2 deregister-image --image-id ${ami} --region ${params.aws_region}") - } - } - // Delete all BYOS snapshot - snapshot_list.each { snapshot -> - if (snapshot) { - sh(script: "${awscli} ec2 delete-snapshot --snapshot-id ${snapshot} --region ${params.aws_region}") - } - } - } + if (params.build_image != null || params.build_last_image) { +// stage('Clean old images') { +// // Get all image ami ids +// image_amis = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=SUSE-Manager-*-BYOS*' --region ${params.aws_region} | jq -r '.Images[].ImageId'", +// returnStdout: true) +// // Get all snapshot ids +// image_snapshots = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=SUSE-Manager-*-BYOS*' --region ${params.aws_region} | jq -r '.Images[].BlockDeviceMappings[0].Ebs.SnapshotId'", +// returnStdout: true) +// +// String[] ami_list = image_amis.split("\n") +// String[] snapshot_list = image_snapshots.split("\n") +// +// // Deregister all BYOS images +// ami_list.each { ami -> +// if (ami) { +// sh(script: "${awscli} ec2 deregister-image --image-id ${ami} --region ${params.aws_region}") +// } +// } +// // Delete all BYOS snapshot +// snapshot_list.each { snapshot -> +// if (snapshot) { +// sh(script: "${awscli} ec2 delete-snapshot --snapshot-id ${snapshot} --region ${params.aws_region}") +// } +// } +// } stage('Download last ami image') { sh "rm -rf ${resultdir}/images" sh "mkdir -p ${resultdir}/images" - sh(script: "curl ${suma43_build_url} > images.html") - server_image_name = sh(script: "grep -oP '(?<=href=\")SUSE-Manager-Server-BYOS.*EC2-Build.*raw.xz(?=\")' images.html", returnStdout: true).trim() - proxy_image_name = sh(script: "grep -oP '(?<=href=\")SUSE-Manager-Proxy-BYOS.*EC2-Build.*raw.xz(?=\")' images.html", returnStdout: true).trim() - - sh(script: "cd ${resultdir}/images; wget ${suma_43_build_url}${server_image_name}") - sh(script: "cd ${resultdir}/images; wget ${suma_43_build_url}${proxy_image_name}") - sh(script: "ec2uploadimg -f /home/jenkins/.ec2utils.conf -a test --backing-store ssd --machine 'x86_64' --virt-type hvm --sriov-support --ena-support --verbose --regions '${params.aws_region}' -d 'build_suma_server' --wait-count 3 -n '${server_image_name}' '${resultdir}/images/${server_image_name}'") - sh(script: "ec2uploadimg -f /home/jenkins/.ec2utils.conf -a test --backing-store ssd --machine 'x86_64' --virt-type hvm --sriov-support --ena-support --verbose --regions '${params.aws_region}' -d 'build_suma_proxy' --wait-count 3 -n '${proxy_image_name}' '${resultdir}/images/${proxy_image_name}'") - env.server_ami = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=${server_image_name}' --region ${params.aws_region}| jq -r '.Images[0].ImageId'", - returnStdout: true).trim() - env.proxy_ami = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=${proxy_image_name}' --region ${params.aws_region} | jq -r '.Images[0].ImageId'", + if (params.build_last_image) { + sh(script: "curl ${url_build_image} > images.html") + server_raw_image = sh(script: "grep -oP '(?<=href=\"./).*Manager-Server-.*BYOS.x86.*EC2-Build.*raw.xz(?=\")' images.html", returnStdout: true).trim() + build_image = "${url_build_image}${server_raw_image}" + } + def server_image_name = extractBuildName(build_image) + sh "cd ${resultdir}/images; wget ${build_image}" + sh "ec2uploadimg -a default --backing-store ssd --machine 'x86_64' --virt-type hvm --sriov-support --wait-count 3 --ena-support --verbose --regions '${params.aws_region}' -n '${server_image_name[0]}' -d 'build image' --ssh-key-pair 'testing-suma' --private-key-file '/home/jenkins/.ssh/testing-suma.pem' --security-group-ids '${security_group_id}' --vpc-subnet ${subnet_id} --type 't2.2xlarge' --user 'ec2-user' -e '${image_help_ami}' '${resultdir}/images/${server_image_name[1]}'" + server_ami = sh(script: "${awscli} ec2 describe-images --filters 'Name=name,Values=${server_image_name[0]}' --region ${params.aws_region}| jq -r '.Images[0].ImageId'", returnStdout: true).trim() + sh script:"echo SERVER_AMI = \\\"${server_ami}\\\" >> ${aws_mirror_dir}/terraform.tfvars" } } }, @@ -136,7 +166,8 @@ def run(params) { env.aws_configuration = aws_configuration + "]\n" writeFile file: "${aws_mirror_dir}/terraform.tfvars", text: aws_configuration, encoding: "UTF-8" // Deploy empty AWS mirror - sh "set +x; source /home/jenkins/.credentials set -x; source /home/jenkins/.registration set -x; export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; ./terracumber-cli ${aws_mirror_params} --logfile ${resultdirbuild}/sumaform-mirror-aws.log --init --taint '.*(domain|main_disk|data_disk|database_disk).*' --runstep provision --sumaform-backend aws" + sh "export TF_LOG=INFO; export TF_LOG_PATH=${aws_mirror_dir}/terraform.log" + + "; export GODEBUG=asyncpreemptoff=1; set +x; source /home/jenkins/.credentials set -x; source /home/jenkins/.registration set -x; export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; ./terracumber-cli ${aws_mirror_params} --logfile ${resultdirbuild}/sumaform-mirror-aws.log --init --taint '.*(domain|main_disk).*' --runstep provision --sumaform-backend aws" } } @@ -160,7 +191,7 @@ def run(params) { sh "ssh ${ssh_option} ${user}@${mirror_hostname_local} 'scp ${ssh_option} -i /root/testing-suma.pem /root/mirror.tar.gz ec2-user@${mirror_hostname_aws_public}:/home/ec2-user/' " sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo tar -xvf /home/ec2-user/mirror.tar.gz -C /srv/mirror/' " sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo rsync -a /srv/mirror/ibs/ /srv/mirror' " - sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo rsync -a /srv/mirror/download/ibs/ /srv/mirror' " + sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo rsync -a /srv/mirror/download/ibs/ /srv/mirror' || true" sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo rm -rf /srv/mirror/ibs' " sh "ssh ${ssh_option} -i ${params.key_file} ec2-user@${mirror_hostname_aws_public} 'sudo rm -rf /srv/mirror/download/ibs' " } @@ -175,34 +206,49 @@ def run(params) { } } + stage('Product changes') { + if (params.show_product_changes) { + sh """ + # Comparison between: + # - the previous git revision of spacewalk (or uyuni) repository pushed in IBS (or OBS) + # - the git revision of the current spacewalk (or uyuni) repository pushed in IBS (or OBS) + # Note: This is a trade-off, we should be comparing the git revisions of all the packages composing our product + # For that extra mile, we need a new tag in the repo metadata of each built, with the git revision of the related repository. + """ + sh script:"./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/; git --no-pager log --pretty=format:\"%h %<(16,trunc)%cn %s %d\" ${previous_commit}..${product_commit}'", returnStatus:true + } else { + println("Product changes disabled, checkbox 'show_product_changes' was not enabled'") + } + } + if (params.must_deploy) { stage("Deploy AWS with MU") { int count = 0 // Replace internal repositories by mirror repositories - sh "sed -i 's/download.suse.de/${mirror_hostname_aws_private}/g' ${WORKSPACE}/custom_repositories.json" - sh "sed -i 's/ibs\\///g' ${WORKSPACE}/custom_repositories.json" +// sh "sed -i 's/download.suse.de/${mirror_hostname_aws_private}/g' ${WORKSPACE}/custom_repositories.json" +// sh "sed -i 's/ibs\\///g' ${WORKSPACE}/custom_repositories.json" // Deploying AWS server using MU repositories - sh "echo \"export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TF_VAR_MIRROR=${env.mirror_hostname_aws_private}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; export TF_VAR_SERVER_AMI=${env.server_ami}; export TF_VAR_PROXY_AMI=${env.proxy_ami}; ./terracumber-cli ${common_params} --logfile ${resultdirbuild}/sumaform-aws.log --init --taint '.*(domain|main_disk|data_disk|database_disk).*' --runstep provision --custom-repositories ${WORKSPACE}/custom_repositories.json --sumaform-backend aws\"" - retry(count: 3) { - sh "set +x; source /home/jenkins/.credentials set -x; source /home/jenkins/.registration set -x; export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TF_VAR_MIRROR=${env.mirror_hostname_aws_private}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; export TF_VAR_SERVER_AMI=${env.server_ami}; export TF_VAR_PROXY_AMI=${env.proxy_ami}; ./terracumber-cli ${common_params} --logfile ${resultdirbuild}/sumaform-aws.log --init --taint '.*(domain|main_disk|data_disk|database_disk).*' --runstep provision --sumaform-backend aws" +// sh "echo \"export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TF_VAR_MIRROR=${env.mirror_hostname_aws_private}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; export TF_VAR_SERVER_AMI=${env.server_ami}; export TF_VAR_PROXY_AMI=${env.proxy_ami}; ./terracumber-cli ${common_params} --logfile ${resultdirbuild}/sumaform-aws.log --init --taint '.*(domain|main_disk|data_disk|database_disk).*' --runstep provision --custom-repositories ${WORKSPACE}/custom_repositories.json --sumaform-backend aws\"" + retry(count: 1) { + sh "export TF_LOG=INFO; export TF_LOG_PATH=${aws_mirror_dir}/terraform.log; export GODEBUG=asyncpreemptoff=1; set +x; source /home/jenkins/.credentials set -x; source /home/jenkins/.registration set -x; export TF_VAR_CUCUMBER_GITREPO=${params.cucumber_gitrepo}; export TF_VAR_CUCUMBER_BRANCH=${params.cucumber_ref}; export TF_VAR_MIRROR=${env.mirror_hostname_aws_private}; export TERRAFORM=${params.terraform_bin}; export TERRAFORM_PLUGINS=${params.terraform_bin_plugins}; export TF_VAR_SERVER_AMI=${env.server_ami}; export TF_VAR_PROXY_AMI=${env.proxy_ami}; ./terracumber-cli ${common_params} --logfile ${resultdirbuild}/sumaform-aws.log --init --taint '.*(domain|main_disk).*' --runstep provision --sumaform-backend aws" deployed_aws = true } } } stage('Sanity Check') { - sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:sanity_check'" + sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; ${env.exports} rake cucumber:sanity_check'" } stage('Core - Setup') { if (params.must_run_core && (deployed_aws || !params.must_deploy)) { - sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:core'" - sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake cucumber:reposync'" + sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; ${env.exports} rake cucumber:core'" + sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; ${env.exports} rake cucumber:reposync'" } } stage('Core - Initialize clients') { if (params.must_init_clients) { - sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; rake ${params.rake_namespace}:init_clients'" + sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd 'cd /root/spacewalk/testsuite; ${env.exports} rake ${params.rake_namespace}:init_clients'" } } stage('Secondary features') { @@ -211,12 +257,12 @@ def run(params) { if (params.functional_scopes) { exports += "export TAGS=${params.functional_scopes}; " } - def statusCode1 = sh script: "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd '${exports} cd /root/spacewalk/testsuite; rake cucumber:secondary'", returnStatus: true - def statusCode2 = sh script: "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd '${exports} cd /root/spacewalk/testsuite; rake ${params.rake_namespace}:secondary_parallelizable'", returnStatus: true - sh "exit \$(( ${statusCode1}|${statusCode2} ))" + def statusCode1 = sh script: "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd '${exports} cd /root/spacewalk/testsuite; ${env.exports} rake cucumber:secondary'", returnStatus: true + def statusCode2 = sh script: "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd '${exports} cd /root/spacewalk/testsuite; ${env.exports} rake ${params.rake_namespace}:secondary_parallelizable'", returnStatus: true + def statusCode3 = sh script: "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/testsuite.log --runstep cucumber --cucumber-cmd '${exports} cd /root/spacewalk/testsuite; ${env.exports} rake ${params.rake_namespace}:secondary_finishing'", returnStatus: true + sh "exit \$(( ${statusCode1}|${statusCode2}|${statusCode3} ))" } } - } finally { stage('Save TF state') { @@ -250,17 +296,28 @@ def run(params) { // junit allowEmptyResults: true, testResults: "${junit_resultdir}/*.xml" } // Send email - sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/mail.log --runstep mail" +// sh "./terracumber-cli ${common_params} --logfile ${resultdirbuild}/mail.log --runstep mail" // Clean up old results sh "./clean-old-results -r ${resultdir}" - // Fail pipeline if client stages failed - if (client_stage_result_fail) { - error("Client stage failed") - } - sh "exit ${result_error}" + sh "exit ${error}" } } } } +def extractBuildName(String url) { + def pattern = ~/\/([^\/]*Manager-(?:Server|Proxy)-[^\/]*)-[^\/]*BYOS[^\/]*-Build(\d+\.\d+)\.raw\.xz/ + def matcher = (url =~ pattern) + def lastIndex = url.lastIndexOf('/') + def fileImageName = url.substring(lastIndex + 1) + + if (matcher.find()) { + def imageName = matcher.group(1) + def buildNumber = matcher.group(2) + return ["${imageName}-build${buildNumber}", fileImageName] + } else { + return null + } +} + return this diff --git a/jenkins_pipelines/environments/manager-5.0-dev-acceptance-tests-AWS b/jenkins_pipelines/environments/manager-5.0-dev-acceptance-tests-AWS new file mode 100644 index 000000000..1e0b6a414 --- /dev/null +++ b/jenkins_pipelines/environments/manager-5.0-dev-acceptance-tests-AWS @@ -0,0 +1,47 @@ +#!/usr/bin/env groovy + +node('sumaform-cucumber') { + properties([ + buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '3')), + disableConcurrentBuilds(), + parameters([ + string(name: 'cucumber_gitrepo', defaultValue: 'https://github.com/uyuni-project/uyuni.git', description: 'Testsuite Git Repository'), + string(name: 'cucumber_ref', defaultValue: 'master', description: 'Testsuite Git reference (branch, tag...)'), + string(name: 'tf_file', defaultValue: 'SUSEManager-5.0-build-image-AWS.tf', description: 'Path to the tf file to be used'), + string(name: 'sumaform_gitrepo', defaultValue: 'https://github.com/uyuni-project/sumaform.git', description: 'Sumaform Git Repository'), + string(name: 'sumaform_ref', defaultValue: 'master', description: 'Sumaform Git reference (branch, tag...)'), + choice(name: 'sumaform_backend', choices: ['libvirt', 'aws'], description: 'Sumaform backend to be used (see https://github.com/uyuni-project/sumaform#backend-choice)'), + choice(name: 'terraform_bin', choices: ['/usr/bin/terraform'], description: 'Terraform binary path'), + choice(name: 'terraform_bin_plugins', choices: ['/usr/bin'], description: 'Terraform plugins path'), + string(name: 'terraform_parallelism', defaultValue: '', description: 'Advanced: Define the number of parallel resource operations for terraform'), + string(name: 'terracumber_gitrepo', defaultValue: 'https://github.com/uyuni-project/terracumber.git', description: 'Terracumber Git Repository'), + string(name: 'terracumber_ref', defaultValue: 'master', description: 'Terracumber Git ref (branch, tag...)'), + booleanParam(name: 'prepare_aws_env', defaultValue: true, description: 'Create local and AWS mirror and upload data to AWS mirror'), + booleanParam(name: 'must_deploy', defaultValue: true, description: 'Deploy'), + booleanParam(name: 'must_run_core', defaultValue: true, description: 'Run Core features'), + booleanParam(name: 'must_init_clients', defaultValue: true, description: 'Run init clients'), + booleanParam(name: 'must_secondary', defaultValue: true, description: 'Run secondary featuress'), + booleanParam(name: 'show_product_changes', defaultValue: true, description: 'Show the product changes since the last build'), + choice(name: 'rake_namespace', choices: ['cucumber', 'parallel'], description: 'Choose [parallel] (Clients and some features will run in parallel) or [cucumber] (all sequential)'), + extendedChoice(name: 'functional_scopes', multiSelectDelimiter: ',', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', visibleItemCount: 30, value: '@scope_smdba,@scope_spacecmd,@scope_spacewalk_utils,@scope_visualization,@scope_notification_message,@scope_virtual_host_manager,@scope_subscription_matching,@scope_formulas,@scope_sp_migration,@scope_cve_audit,@scope_onboarding,@scope_content_lifecycle_management,@scope_res,@scope_recurring_actions,@scope_maintenance_windows,@scope_building_container_images,@scope_kubernetes_integration,@scope_openscap,@scope_deblike,@scope_action_chains,@scope_salt_ssh,@scope_tomcat,@scope_changing_software_channels,@scope_monitoring,@scope_salt,@scope_cobbler,@scope_sumatoolbox,@scope_virtualization,@scope_hub,@scope_retail,@scope_configuration_channels,@scope_content_staging,@scope_proxy,@scope_traditional_client,@scope_api,@scope_power_management,@scope_retracted_patches,@scope_ansible,@scope_reportdb,@scope_containerized_proxy', description: 'Choose the functional scopes that you want to test'), + string(name: 'aws_region', defaultValue: 'eu-central-1', description: 'Describe the AWS region where to deploy the server'), + string(name: 'aws_availability_zone', defaultValue: 'eu-central-1a', description: 'Describe the AWS availability zone to deploy the server'), + string(name: 'key_file', defaultValue: '/home/jenkins/.ssh/testing-suma.pem', description: 'Path to SSH private key to access instance in AWS'), + string(name: 'key_name', defaultValue: 'testing-suma', description: 'SSH key name in AWS'), + text(name: 'allowed_IPS', defaultValue: '65.132.116.254', description: 'Add the public IPs to add to AWS ingress security group ( keep default Jenkins address ) separated by new line' ), + booleanParam(name: 'build_last_image', defaultValue: false, description: 'Get the last available image for 5.0, while overwrite build_image'), + text(name: 'build_image', description: 'Build image url' ) + ]) + ]) + + stage('Checkout pipeline') { + checkout scm + } + timeout(activity: false, time: 14, unit: 'HOURS') { + //Capybara configuration + capybara_timeout = 10 + default_timeout = 250 + def pipeline = load "jenkins_pipelines/environments/common/pipeline-aws.groovy" + pipeline.run(params) + } +} diff --git a/terracumber_config/tf_files/SUSEManager-5.0-build-image-AWS.tf b/terracumber_config/tf_files/SUSEManager-5.0-build-image-AWS.tf new file mode 100644 index 000000000..8f162042c --- /dev/null +++ b/terracumber_config/tf_files/SUSEManager-5.0-build-image-AWS.tf @@ -0,0 +1,396 @@ + +// Mandatory variables for terracumber +variable "URL_PREFIX" { + type = string + default = "https://ci.suse.de/view/Manager/view/Manager-50/job/manager-5.0-build-image-aws" +} + +// Not really used as this is for --runall parameter, and we run cucumber step by step +variable "CUCUMBER_COMMAND" { + type = string + default = "export PRODUCT='SUSE-Manager' && run-testsuite" +} + +variable "CUCUMBER_GITREPO" { + type = string + default = "https://github.com/uyuni-project/uyuni.git" +} + +variable "CUCUMBER_BRANCH" { + type = string + default = "master" +} + +variable "CUCUMBER_RESULTS" { + type = string + default = "/root/spacewalk/testsuite" +} + +variable "MAIL_SUBJECT" { + type = string + default = "Results Manager5.0-WS-MU $status: $tests scenarios ($failures failed, $errors errors, $skipped skipped, $passed passed)" +} + +variable "MAIL_TEMPLATE" { + type = string + default = "../mail_templates/mail-template-jenkins.txt" +} + +variable "MAIL_SUBJECT_ENV_FAIL" { + type = string + default = "Results Manager5.0-AWS-MU: Environment setup failed" +} + +variable "MAIL_TEMPLATE_ENV_FAIL" { + type = string + default = "../mail_templates/mail-template-jenkins-env-fail.txt" +} + +variable "MAIL_FROM" { + type = string + default = "galaxy-noise@suse.de" +} + +variable "MAIL_TO" { + type = string + default = "galaxy-noise@suse.de" +} + +// sumaform specific variables +variable "SCC_USER" { + type = string +} + +variable "SCC_PASSWORD" { + type = string +} + +variable "GIT_USER" { + type = string + default = null // Not needed for master, as it is public +} + +variable "GIT_PASSWORD" { + type = string + default = null // Not needed for master, as it is public +} + +variable "REGION" { + type = string + default = null +} + +variable "MIRROR"{ + type = string + default = null +} + +variable "AVAILABILITY_ZONE" { + type = string + default = null +} + +variable "KEY_FILE" { + type = string + default = "/home/jenkins/.ssh/testing-suma.pem" +} + +variable "KEY_NAME" { + type = string + default = "testing-suma" +} + +variable "SERVER_REGISTRATION_CODE" { + type = string + default = null +} + +variable "PROXY_REGISTRATION_CODE" { + type = string + default = null +} + +variable "SLES_REGISTRATION_CODE" { + type = string + default = null +} + +variable "ALLOWED_IPS" { + type = list(string) + default = [] +} + +variable "NAME_PREFIX" { + type = string + default = null +} + +variable "SERVER_AMI" { + type = string + default = "slemicro55" +} + +locals { + domain = "suma.ci.aws" +} + +provider "aws" { + region = var.REGION +} + +module "base" { + source = "./modules/base" + + cc_username = var.SCC_USER + cc_password = var.SCC_PASSWORD + name_prefix = var.NAME_PREFIX + mirror = var.MIRROR + testsuite = true + use_avahi = false + use_eip_bastion = false + is_server_paygo_instance = false +# images = [ "opensuse155o"] +# images = ["rocky8", "opensuse155o", "sles15sp5o", "sles15sp4o", "ubuntu2204"] + provider_settings = { + availability_zone = var.AVAILABILITY_ZONE + region = var.REGION + ssh_allowed_ips = var.ALLOWED_IPS + key_name = var.KEY_NAME + key_file = var.KEY_FILE + route53_domain = local.domain + bastion_host = "${var.NAME_PREFIX}-bastion.${local.domain}" + } +} + + +module "mirror" { + source = "./modules/mirror" + base_configuration = module.base.configuration + disable_cron = true + provider_settings = { + public_instance = true + } + image = "opensuse155o" +} + +module "server" { + source = "./modules/server_containerized" + base_configuration = merge(module.base.configuration, + { + mirror = null + }) + name = "server" + product_version = "head-build_image" + repository_disk_size = 1500 + image = var.SERVER_AMI +# server_registration_code = var.SERVER_REGISTRATION_CODE + + runtime = "podman" + container_repository = "registry.suse.com/suse/manager/5.0/x86_64" + // Most recent code. Enable again once Beta 2 will be approved: + // container_repository = "registry.suse.de/devel/galaxy/manager/head/containerfile/suse/manager/5.0/x86_64" + + + java_debugging = false + auto_accept = false + disable_firewall = false + allow_postgres_connections = false + skip_changelog_import = false + mgr_sync_autologin = false + create_sample_channel = false + create_sample_activation_key = false + create_sample_bootstrap_script = false + publish_private_ssl_key = false + use_os_released_updates = true + disable_download_tokens = false + large_deployment = true + ssh_key_path = "./salt/controller/id_rsa.pub" + from_email = "root@suse.de" + provider_settings = { + instance_type = "m6a.xlarge" + } + install_salt_bundle = false + //server_additional_repos + +} + +module "proxy" { + + source = "./modules/proxy" + base_configuration = module.base.configuration + server_configuration = module.server.configuration + product_version = "4.3-released" + name = "proxy" + proxy_registration_code = var.PROXY_REGISTRATION_CODE + + auto_register = false + auto_connect_to_master = false + download_private_ssl_key = false + install_proxy_pattern = false + auto_configure = false + generate_bootstrap_script = false + publish_private_ssl_key = false + use_os_released_updates = false + proxy_containerized = false + ssh_key_path = "./salt/controller/id_rsa.pub" + additional_packages = [ "venv-salt-minion" ] + install_salt_bundle = true + //proxy_additional_repos + +} + +# module "proxy_containerized" { +# source = "./modules/proxy_containerized" +# base_configuration = module.base_core.configuration +# product_version = "head" +# name = "pxy" +# +# server_configuration = module.server.configuration +# runtime = "podman" +# # container_repository = "registry.suse.de/suse/sle-15-sp6/update/products/manager50/containerfile/suse/manager/5.0/x86_64" +# // Most recent code. Enable again once Beta 2 will be approved: +# // container_repository = "registry.suse.de/devel/galaxy/manager/head/containerfile/suse/manager/5.0/x86_64" +# auto_configure = false +# ssh_key_path = "./salt/controller/id_rsa.pub" +# } + +module "suse-client" { + + source = "./modules/client" + base_configuration = module.base.configuration + name = "cli-sles15" + image = "sles15sp4o" + product_version = "4.3-released" + server_configuration = module.server.configuration + sles_registration_code = var.SLES_REGISTRATION_CODE + auto_register = false + use_os_released_updates = false + ssh_key_path = "./salt/controller/id_rsa.pub" + additional_packages = [ "venv-salt-minion" ] + install_salt_bundle = true + provider_settings = { + instance_type = "t3a.medium" + } + //sle15sp4-client_additional_repos +} + +module "suse-minion" { + source = "./modules/minion" + base_configuration = module.base.configuration + product_version = "4.3-released" + name = "min-sles15" + image = "sles15sp4o" + server_configuration = module.server.configuration + sles_registration_code = var.SLES_REGISTRATION_CODE + auto_connect_to_master = false + use_os_released_updates = true + ssh_key_path = "./salt/controller/id_rsa.pub" + additional_packages = [ "venv-salt-minion" ] + install_salt_bundle = true + provider_settings = { + instance_type = "t3a.medium" + } + //sle15sp4-minion_additional_repos + +} + +module "suse-sshminion" { + source = "./modules/sshminion" + base_configuration = module.base.configuration + product_version = "4.3-released" + name = "minssh-sles15" + image = "sles15sp4o" + sles_registration_code = var.SLES_REGISTRATION_CODE + use_os_released_updates = true + ssh_key_path = "./salt/controller/id_rsa.pub" + gpg_keys = ["default/gpg_keys/galaxy.key"] + additional_packages = [ "venv-salt-minion" , "iptables"] + install_salt_bundle = true + provider_settings = { + instance_type = "t3a.medium" + } + +} + +module "debian-minion" { + name = "min-ubuntu2204" + image = "ubuntu2204" + source = "./modules/minion" + base_configuration = module.base.configuration + product_version = "4.3-released" + server_configuration = module.server.configuration + auto_connect_to_master = false + ssh_key_path = "./salt/controller/id_rsa.pub" + additional_packages = [ "venv-salt-minion" ] + install_salt_bundle = true + provider_settings = { + instance_type = "t3a.medium" + } +} + +module "rocky8-minion" { + source = "./modules/minion" + base_configuration = module.base.configuration + product_version = "4.3-released" + name = "min-rocky8" + image = "rocky8" + server_configuration = module.server.configuration + auto_connect_to_master = false + use_os_released_updates = false + ssh_key_path = "./salt/controller/id_rsa.pub" + additional_packages = [ "venv-salt-minion" ] + install_salt_bundle = true + provider_settings = { + instance_type = "t3a.medium" + } +} + +module "controller" { + source = "./modules/controller" + base_configuration = module.base.configuration + name = "ctl" + provider_settings = { + memory = 16384 + vcpu = 8 + } + swap_file_size = null + no_mirror = true + is_using_build_image = true + is_using_scc_repositories = true + // Cucumber repository configuration for the controller + git_username = var.GIT_USER + git_password = var.GIT_PASSWORD + git_repo = var.CUCUMBER_GITREPO + branch = var.CUCUMBER_BRANCH + + server_configuration = module.server.configuration + proxy_configuration = module.proxy.configuration + client_configuration = module.suse-client.configuration + minion_configuration = module.suse-minion.configuration +// buildhost_configuration = module.build-host.configuration + sshminion_configuration = module.suse-sshminion.configuration +# redhat_configuration = module.redhat-minion.configuration + debian_configuration = module.debian-minion.configuration + +} + +output "bastion_public_name" { + value = lookup(module.base.configuration, "bastion_host", null) +} + +output "aws_mirrors_private_name" { + value = module.mirror.configuration.hostnames +} + +output "aws_mirrors_public_name" { + value = module.mirror.configuration.public_names +} + +output "configuration" { + value = { + controller = module.controller.configuration + bastion = { + hostname = lookup(module.base.configuration, "bastion_host", null) + } + } +} diff --git a/terracumber_config/tf_files/aws_mirror.tf b/terracumber_config/tf_files/aws_mirror.tf index 286e53d26..385f9bba2 100644 --- a/terracumber_config/tf_files/aws_mirror.tf +++ b/terracumber_config/tf_files/aws_mirror.tf @@ -133,6 +133,7 @@ module "base" { testsuite = true use_avahi = false use_eip_bastion = false +# images = [ "opensuse155o"] provider_settings = { availability_zone = var.AVAILABILITY_ZONE region = var.REGION diff --git a/terracumber_config/tf_files/local_mirror.tf b/terracumber_config/tf_files/local_mirror.tf index ad7f3df7b..07a250d23 100644 --- a/terracumber_config/tf_files/local_mirror.tf +++ b/terracumber_config/tf_files/local_mirror.tf @@ -92,7 +92,7 @@ terraform { } provider "libvirt" { - uri = "qemu+tcp://grog.mgr.prv.suse.net/system" + uri = "qemu+tcp://suma-05.mgr.suse.de/system" } locals { @@ -107,7 +107,8 @@ module "base" { name_prefix = "mirror-mu-aws-" images = [ "opensuse155o"] - + mirror = "minima-mirror-ci-bv.mgr.suse.de" + use_mirror_images = true provider_settings = { pool = local.pool network_name = null @@ -130,7 +131,7 @@ module "mirror" { // volume_snapshot_id = data.aws_ebs_snapshot.data_disk_snapshot.id } provider_settings = { - mac = "52:54:00:ba:b7:98" + mac = "52:54:00:ba:b7:99" memory = 4096 } }