From 296f80350066cd35f832921f4568faff53b60f77 Mon Sep 17 00:00:00 2001 From: Jeremy Poulin Date: Tue, 26 Feb 2019 15:29:21 -0500 Subject: [PATCH] Release v1.2.2 (#37) * Run scripts should now ignore errors, and hopefully produce files as intended * Artifacts should now be created in the running directory * Creating individual artifact directories and doing result scan after * Fixed a ws issue with run_scripts playbook * Run scripts did not accept the chdir arg * Fixed typo for scripts results variable * Adding archive step to run tests since it should really be part of the default test * Explicitly calling archive since vars my not be referencable from other vars * Linchpin workspace should now default to libraries spec * Updated tests and fixed codenarc issues * Update release version and add parsing function * Codenarc narcing all over the new function * Updating CI Message to have better error handling and a map return * SSH mode support and remote target host update * Added lines to cover installing cert for RCM tools * Installing certs on host so we can pull down dev imgs * Ensuring backup cert install is still available * Fixed curl requests so that they will install certs correctly * Credentials should now be installed correctly on SSH mode hosts, and guaranteed install when rhpkg is specified * Moved script object into the final closure, so objects can be passed to it in SSH mode. * Updated logic to allow for non-root ssh mode, secret file injection, and env exports * Inject secret locations failed, so attemting to remove layer of indirection * Updating utils to once against attempt variable injection * Codenarc is a narc * Attempting to escape $ so that file in inject * Updated local install to mkdirs before copying files there * Removed Jenkins krb principal for files list * We should now install the correct rhpkg tools per the rhel host spec * Added overridable map for inventory vars * Fixed syntax for NoOpProvisioner inventory vars override * Renamed inventoryVars, updated tests, and ensured proper functioning for NoOpProvisioner * Variable naming convention consistency in LinchPin workspace * Reading hostname and ensuring only the hostname is picked up * Package name fix for RHEL-8 * Renamed resource playbooks to indicate what they were * Fixed distribution version * Fixed ternary grouping * Fixing python package install on RHEL 8 * Fixed path issue for renamed playbooks * RHEL 7 targets should no longer attempt to install python 3 * Renamed test output file to runlog * CI message should now be cleaned up * Pulled script var back out into the genericInstall since JNLP mode needs to be able to change the node BEFORE calling the sh step --- resources/{ => playbooks}/collect_results.yml | 0 resources/playbooks/run_scripts.yml | 64 +++++++++++++ resources/run_scripts.yml | 42 --------- src/com/redhat/ci/Utils.groovy | 93 +++++++++++++++---- .../redhat/ci/hosts/ProvisionedHost.groovy | 2 + src/com/redhat/ci/hosts/TargetHost.groovy | 6 ++ .../ci/provisioner/ProvisioningConfig.groovy | 12 ++- .../provisioners/LinchPinProvisioner.groovy | 12 +-- .../ci/provisioners/NoOpProvisioner.groovy | 16 ++-- test/com/redhat/ci/UtilsTest.groovy | 85 +++++++++++++++-- .../provisioner/ProvisioningConfigTest.groovy | 8 ++ .../LinchPinProvisionerTest.groovy | 3 +- .../provisioners/NoOpProvisionerTest.groovy | 7 +- vars/getCIMessage.groovy | 9 ++ vars/runTests.groovy | 41 ++++++-- workspace/PinFile | 6 ++ 16 files changed, 310 insertions(+), 96 deletions(-) rename resources/{ => playbooks}/collect_results.yml (100%) create mode 100644 resources/playbooks/run_scripts.yml delete mode 100644 resources/run_scripts.yml create mode 100644 vars/getCIMessage.groovy diff --git a/resources/collect_results.yml b/resources/playbooks/collect_results.yml similarity index 100% rename from resources/collect_results.yml rename to resources/playbooks/collect_results.yml diff --git a/resources/playbooks/run_scripts.yml b/resources/playbooks/run_scripts.yml new file mode 100644 index 0000000..2c045ea --- /dev/null +++ b/resources/playbooks/run_scripts.yml @@ -0,0 +1,64 @@ +--- +- name: "Run Scripts on each Inventory Host" + hosts: all + gather_facts: true + vars_prompt: + - name: test_dir + prompt: "Please enter the path to your tests" + + tasks: + - name: install rsync and the utilities to copy the tests to the remote host + package: + name: "{{ item }}" + state: latest + with_items: + - rsync + - "{{ ((ansible_facts['distribution'] == 'RedHat' or ansible_facts['distribution'] == 'CentOS') and + ansible_facts['distribution_major_version'] | int >= 8) | + ternary('python3-libselinux', 'libselinux-python') }}" + - "{{ ((ansible_facts['distribution'] == 'RedHat' or ansible_facts['distribution'] == 'CentOS') and + ansible_facts['distribution_major_version'] | int >= 8) | + ternary('python3', 'python2') }}" + + - name: create a directory for the tests on the remote host + file: + path: "/tmp/{{ test_dir }}" + state: directory + + - name: copy the tests onto the hosts where they will be executed + synchronize: + src: "{{ test_dir }}/scripts" + dest: "/tmp/{{ test_dir }}" + mode: push + ignore_errors: true + + - name: scan and find the test scripts directory + find: + recurse: false + paths: "/tmp/{{ test_dir }}/scripts" + file_type: directory + register: scripts_dir + + - name: loop through script directories and create artifacts directory + file: + path: "{{ script_dir }}/artifacts" + state: directory + loop: "{{ scripts_dir.files | map(attribute='path') | list }}" + loop_control: + loop_var: script_dir + + - name: loop through script directories, run test, and store artifacts + shell: "bash -x test.sh {{ script_args | default('') }} &> artifacts/{{ ansible_architecture }}-runlog.txt" + args: + chdir: "{{ script_dir }}" + loop: "{{ scripts_dir.files | map(attribute='path') | list }}" + loop_control: + loop_var: script_dir + ignore_errors: yes + register: scripts + + - name: fail if the return code is not 0 + fail: + msg: "The command ({{ item.cmd }}) failed with return code {{ item.rc }}" + when: item.rc != 0 + with_items: "{{ scripts.results }}" diff --git a/resources/run_scripts.yml b/resources/run_scripts.yml deleted file mode 100644 index 7a2cee4..0000000 --- a/resources/run_scripts.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -- name: "Run Scripts on each Inventory Host" - hosts: all - gather_facts: true - vars_prompt: - - name: test_dir - prompt: "Please enter the path to your tests" - - tasks: - - debug: - msg: "{{ test_dir }}" - - - package: - name: "{{ item }}" - state: latest - with_items: - - rsync - - libselinux-python - - python2 - - - file: - path: "/tmp/{{ test_dir }}" - state: directory - - - synchronize: - src: "{{ test_dir }}/scripts" - dest: "/tmp/{{ test_dir }}" - mode: push - ignore_errors: true - - - find: - recurse: false - paths: "/tmp/{{ test_dir }}/scripts" - file_type: directory - register: scripts - - - shell: "mkdir -p artifacts; bash -x test.sh {{ script_args | default('') }} &> artifacts/{{ ansible_architecture }}-output.txt" - args: - chdir: "{{ script_dir }}" - loop: "{{ scripts.files | map(attribute='path') | list }}" - loop_control: - loop_var: script_dir diff --git a/src/com/redhat/ci/Utils.groovy b/src/com/redhat/ci/Utils.groovy index c271589..b146e4d 100644 --- a/src/com/redhat/ci/Utils.groovy +++ b/src/com/redhat/ci/Utils.groovy @@ -12,6 +12,17 @@ class Utils { private static final String SUDO = 'sudo ' private static final String NO_SUDO = '' private static final String INSTALL_FILE = 'install.sh' + private static final String SSH_ARGS = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' + private static final String SSH_IDENTITY = '-i ~/.ssh/id_rsa' + private static final String SSH = "ssh ${SSH_ARGS} ${SSH_IDENTITY}" + private static final String SCP = "scp ${SSH_ARGS} ${SSH_IDENTITY}" + private static final String HOME = '/home/jenkins' + private static final String KEYTAB = 'KEYTAB' + private static final String KRB_PRINCIPAL = 'KRB_PRINCIPAL' + private static final String SSHPRIVKEY = 'SSHPRIVKEY' + private static final String SSHPUBKEY = 'SSHPUBKEY' + private static final String KRBCONF = 'KRBCONF' + private static final String BKRCONF = 'BKRCONF' /** * Attemps to install Ansible. @@ -28,7 +39,7 @@ class Utils { ${sudo}pip install --upgrade pip && ${sudo}pip install --upgrade setuptools && ${sudo}pip install --upgrade ansible - """) + """, null) if (host == null) { return } @@ -44,16 +55,22 @@ class Utils { privileged, sh -> String sudo = privileged ? SUDO : NO_SUDO script.withCredentials([ - script.file(credentialsId:config.keytabCredentialId, variable:'KEYTAB'), + script.file(credentialsId:config.keytabCredentialId, variable:KEYTAB), script.usernamePassword(credentialsId:config.krbPrincipalCredentialId, - usernameVariable:'KRB_PRINCIPAL', + usernameVariable:KRB_PRINCIPAL, passwordVariable:''), - script.file(credentialsId:config.sshPrivKeyCredentialId, variable:'SSHPRIVKEY'), - script.file(credentialsId:config.sshPubKeyCredentialId, variable:'SSHPUBKEY'), - script.file(credentialsId:config.krbConfCredentialId, variable:'KRBCONF'), - script.file(credentialsId:config.bkrConfCredentialId, variable:'BKRCONF'), + script.file(credentialsId:config.sshPrivKeyCredentialId, variable:SSHPRIVKEY), + script.file(credentialsId:config.sshPubKeyCredentialId, variable:SSHPUBKEY), + script.file(credentialsId:config.krbConfCredentialId, variable:KRBCONF), + script.file(credentialsId:config.bkrConfCredentialId, variable:BKRCONF), ]) { - script.env.HOME = '/home/jenkins' + script.env.HOME = HOME + Map context = [ + env:[HOME:HOME], + files:[script.KEYTAB, script.SSHPRIVKEY, + script.SSHPUBKEY, script.KRBCONF, script.BKRCONF], + ] + sh(""" ${sudo}yum install -y krb5-workstation ${sudo}cp ${script.KRBCONF} /etc/krb5.conf @@ -69,7 +86,7 @@ class Utils { chmod 644 ~/.ssh/id_rsa.pub eval "\$(ssh-agent -s)" ssh-add ~/.ssh/id_rsa - """) + """, context) if (host != null) { host.credentialsInstalled = true } @@ -85,18 +102,35 @@ class Utils { genericInstall(script, config, host) { privileged, sh -> String sudo = privileged ? SUDO : NO_SUDO + String distro = host ? host.distro : 'RHEL-7' + String variant = host ? host.variant : 'Server' + if (!distro || !variant || !distro.startsWith('RHEL')) { + script.echo("Installing rhpkg tool is not supported for distro=[${distro}] and variant=[${variant}]") + return + } + String osMajorVersion = distro.find('[0-9]+') + if (!osMajorVersion || osMajorVersion.toInteger() < 5 || osMajorVersion.toInteger() > 8) { + script.echo("RCM rhpkg tool is not available for distro=[${distro}]. Invalid major version=[${osMajorVersion}]") + return + } sh(""" echo "pkgs.devel.redhat.com,10.19.208.80 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAplqWKs26qsoaTxvWn3DFcdbiBxqRLhFngGiMYhbudnAj4li9/VwAJqLm1M6YfjOoJrj9dlmuXhNzkSzvyoQODaRgsjCG5FaRjuN8CSM/y+glgCYsWX1HFZSnAasLDuW0ifNLPR2RBkmWx61QKq+TxFDjASBbBywtupJcCsA5ktkjLILS+1eWndPJeSUJiOtzhoN8KIigkYveHSetnxauxv1abqwQTk5PmxRgRt20kZEFSRqZOJUlcl85sZYzNC/G7mneptJtHlcNrPgImuOdus5CW+7W49Z/1xqqWI/iRjwipgEMGusPMlSzdxDX4JzIx6R53pDpAwSAQVGDz4F9eQ==" | ${sudo}tee -a /etc/ssh/ssh_known_hosts echo "Host pkgs.devel.redhat.com" | ${sudo}tee -a /etc/ssh/ssh_config echo "IdentityFile /home/jenkins/.ssh/id_rsa" | ${sudo}tee -a /etc/ssh/ssh_config + ${sudo}curl -o /etc/pki/ca-trust/source/anchors/RedHat_CA.crt -k -L https://password.corp.redhat.com/cacert.crt + ${sudo}curl -o /etc/pki/ca-trust/source/anchors/PnTDevOps_CA.crt -k -L https://engineering.redhat.com/Eng-CA.crt + ${sudo}curl -o /etc/pki/ca-trust/source/anchors/RH-IT-Root-CA.crt -k -L https://password.corp.redhat.com/RH-IT-Root-CA.crt + ${sudo}update-ca-trust extract + ${sudo}yum install -y yum-utils git - curl -L -O http://download.devel.redhat.com/rel-eng/internal/rcm-tools-rhel-7-server.repo - ${sudo}yum-config-manager --add-repo rcm-tools-rhel-7-server.repo + + curl -L -o rcm-tools.repo http://download.devel.redhat.com/rel-eng/internal/rcm-tools-rhel-${osMajorVersion}-${variant.toLowerCase()}.repo + ${sudo}yum-config-manager --add-repo rcm-tools.repo ${sudo}yum install -y rhpkg git config --global user.name "jenkins" - """) + """, null) if (host != null) { host.rhpkgInstalled = true } @@ -112,7 +146,7 @@ class Utils { // Installation should occur on current node if (host == null) { installWrapper(NO_SUDO) { - shCommand -> + shCommand, context=[:] -> script.sh(shCommand) } return @@ -126,7 +160,7 @@ class Utils { script.node(host.displayName) { installWrapper(SUDO) { - shCommand -> + shCommand, context=[:] -> script.sh(shCommand) } } @@ -139,12 +173,31 @@ class Utils { throw new ProvisioningException('Installing in SSH mode but hostname is invalid.') } - installWrapper(NO_SUDO) { - shCommand -> - script.writeFile(file:INSTALL_FILE, text:shCommand) - String runCommandOnHost = 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + - "-i ~/.ssh/id_rsa root@${host.hostname} < ${INSTALL_FILE}" - script.sh(runCommandOnHost) + installWrapper(host.remoteUser == 'root' ? NO_SUDO : SUDO) { + shCommand, context=[:] -> + // Copy files onto target host + String files = '' + if (context && context.files) { + for (file in context.files) { + files += """ + $SSH ${host.remoteUser}@${host.hostname} mkdir -p \$(dirname "$file") && + $SCP $file ${host.remoteUser}@${host.hostname}:$file;\n + """ + } + } + script.sh(files) + + // Export env vars + String exports = '' + if (context && context.env) { + for (envVar in context.env) { + exports += "export ${envVar.key}=${envVar.value};\n" + } + } + + // Run the actual script + script.writeFile(file:INSTALL_FILE, text:"$exports $shCommand") + script.sh("$SSH ${host.remoteUser}@${host.hostname} < $INSTALL_FILE") } } } diff --git a/src/com/redhat/ci/hosts/ProvisionedHost.groovy b/src/com/redhat/ci/hosts/ProvisionedHost.groovy index 769ad53..112c47e 100644 --- a/src/com/redhat/ci/hosts/ProvisionedHost.groovy +++ b/src/com/redhat/ci/hosts/ProvisionedHost.groovy @@ -56,5 +56,7 @@ class ProvisionedHost extends TargetHost { this.bkrMethod = target.bkrMethod this.reserveDuration = target.reserveDuration this.scriptParams = target.scriptParams + this.remoteUser = target.remoteUser + this.inventoryVars = target.inventoryVars } } diff --git a/src/com/redhat/ci/hosts/TargetHost.groovy b/src/com/redhat/ci/hosts/TargetHost.groovy index 723eade..d6847ff 100644 --- a/src/com/redhat/ci/hosts/TargetHost.groovy +++ b/src/com/redhat/ci/hosts/TargetHost.groovy @@ -38,4 +38,10 @@ class TargetHost extends Host { // String of parameters to pass to script tests String scriptParams = null + + // Remote user to connect with in SSH mode + String remoteUser = 'root' + + // Inventory file variables + Map inventoryVars = [:] } diff --git a/src/com/redhat/ci/provisioner/ProvisioningConfig.groovy b/src/com/redhat/ci/provisioner/ProvisioningConfig.groovy index 15b4497..2c31ed2 100644 --- a/src/com/redhat/ci/provisioner/ProvisioningConfig.groovy +++ b/src/com/redhat/ci/provisioner/ProvisioningConfig.groovy @@ -4,6 +4,7 @@ package com.redhat.ci.provisioner * Configuration needed to provision resources with a Provisioner. */ class ProvisioningConfig { + private static final String RELEASE_VERSION = 'v1.2.2' private static final String KRB_PRINCIPAL_CREDENTIAL_ID_DEFAULT = 'redhat-multiarch-qe-krbprincipal' private static final String KEYTAB_CREDENTIAL_ID_DEFAULT = 'redhat-multiarch-qe-keytab' private static final String SSH_PRIV_KEY_CREDENTIAL_ID_DEFAULT = 'redhat-multiarch-qe-sshprivkey' @@ -11,9 +12,12 @@ class ProvisioningConfig { private static final String JENKINS_SLAVE_CREDENTIAL_ID_DEFAULT = 'jenkins-slave-credentials' private static final String JENKINS_MASTER_URL_DEFAULT = '' private static final String JSWARM_EXTRA_ARGS_DEFAULT = '' + private static final String PROVISIONING_REPO_URL_DEFAULT = + 'https://github.com/redhat-multiarch-qe/multiarch-ci-libraries' + private static final String PROVISIONING_REPO_REF_DEFAULT = RELEASE_VERSION // Provisioner version - String version = 'v1.2.1' + String version = RELEASE_VERSION // Jenkins kubernetes cloud name String cloudName = 'openshift' @@ -34,10 +38,10 @@ class ProvisioningConfig { String provisioningImage = 'provisioner' // Provisioning repo url - String provisioningRepoUrl = 'https://github.com/redhat-multiarch-qe/multiarch-ci-libraries' + String provisioningRepoUrl = PROVISIONING_REPO_URL_DEFAULT // Provisioning repo ref - String provisioningRepoRef = this.version + String provisioningRepoRef = PROVISIONING_REPO_REF_DEFAULT // Provisioning workspace location (needed for LinchPin) // This can reference a relative path in the above repo @@ -116,6 +120,8 @@ class ProvisioningConfig { this.jenkinsSlaveCredentialId = params.JENKINSSLAVECREDENTIALID ?: this.jenkinsSlaveCredentialId this.jenkinsMasterUrl = env.JENKINS_MASTER_URL ?: this.jenkinsMasterUrl this.jswarmExtraArgs = env.JSWARM_EXTRA_ARGS ?: this.jswarmExtraArgs + this.provisioningRepoUrl = params.LIBRARIES_REPO ?: this.provisioningRepoUrl + this.provisioningRepoRef = params.LIBRARIES_REF ?: this.provisioningRepoRef hostTypePriority = [ com.redhat.ci.host.Type.CONTAINER, diff --git a/src/com/redhat/ci/provisioners/LinchPinProvisioner.groovy b/src/com/redhat/ci/provisioners/LinchPinProvisioner.groovy index b1f383b..a550040 100644 --- a/src/com/redhat/ci/provisioners/LinchPinProvisioner.groovy +++ b/src/com/redhat/ci/provisioners/LinchPinProvisioner.groovy @@ -114,12 +114,11 @@ class LinchPinProvisioner extends AbstractProvisioner { if (config.installAnsible) { Utils.installAnsible(script, config, host) } + } - // In JNLP mode, install provisioning credentials directly on the provisioned host - // (Already installed in SSH mode) - if (config.installCredentials) { - Utils.installCredentials(script, config, host) - } + // Install credentials directly on the provisioned host + if (config.installCredentials || config.installRhpkg) { + Utils.installCredentials(script, config, host) } // We can install the RHPKG tool if the user intends to use it. @@ -198,6 +197,7 @@ class LinchPinProvisioner extends AbstractProvisioner { reserve_duration:host.reserveDuration, job_group:host.bkrJobGroup ?: config.jobgroup, hostrequires:getHostRequires(host, config), + inventory_vars:host.inventoryVars, ] JsonOutput.toJson(templateData) @@ -252,7 +252,7 @@ class LinchPinProvisioner extends AbstractProvisioner { } private String getHostname(ProvisionedHost host) { - String getMasterNode = "awk '/\\[master_node\\]/{getline; print}' ${host.inventoryPath}" + String getMasterNode = "awk '/\\[master_node\\]/{getline; print}' ${host.inventoryPath} | cut -d ' ' -f 1" script.sh(returnStdout:true, script:getMasterNode).trim() } } diff --git a/src/com/redhat/ci/provisioners/NoOpProvisioner.groovy b/src/com/redhat/ci/provisioners/NoOpProvisioner.groovy index 8fe6e8c..483bb17 100644 --- a/src/com/redhat/ci/provisioners/NoOpProvisioner.groovy +++ b/src/com/redhat/ci/provisioners/NoOpProvisioner.groovy @@ -91,12 +91,11 @@ class NoOpProvisioner extends AbstractProvisioner { if (config.installAnsible) { Utils.installAnsible(script, config, host) } + } - // In JNLP mode, install provisioning credentials directly on the provisioned host - // (Already installed in SSH mode) - if (config.installCredentials) { - Utils.installCredentials(script, config, host) - } + // Install credentials directly on the provisioned host + if (config.installCredentials || config.installRhpkg) { + Utils.installCredentials(script, config, host) } // We can install the RHPKG tool if the user intends to use it. @@ -173,7 +172,12 @@ class NoOpProvisioner extends AbstractProvisioner { // Build a cinch-compatible inventory using the passing in hostname for (String group in LAYOUT_GROUPS) { - inventory += "[${group}]\n${host.hostname}\n\n" + inventory += "[${group}]\n${host.hostname}" + host.inventoryVars.each { + key, value -> + inventory += " ${key}=${value}" + } + inventory += '\n\n' } // Write and return inventory file path diff --git a/test/com/redhat/ci/UtilsTest.groovy b/test/com/redhat/ci/UtilsTest.groovy index 5955d86..688066f 100644 --- a/test/com/redhat/ci/UtilsTest.groovy +++ b/test/com/redhat/ci/UtilsTest.groovy @@ -10,6 +10,7 @@ import com.redhat.ci.provisioner.Mode * Tests the install script wrapper. */ class UtilsTest { + private static final String SUDO = 'sudo' private static final String INSTALLED = 'Installed' private static final String TEST_HOSTNAME = 'test-host' private static final String NODE_STEP = 'node' @@ -18,9 +19,12 @@ class UtilsTest { private ProvisioningConfig config = null private PipelineTestScript script = null - private final Closure genericInstall = { + private final Closure installWrapper = { sudo, sh -> - sh(INSTALLED) + if (sudo) { + script.echo(SUDO) + } + sh(null) } private final Closure node = { @@ -37,7 +41,12 @@ class UtilsTest { @Before void init() { - validHost = new ProvisionedHost(hostname:TEST_HOSTNAME, displayName:TEST_HOSTNAME) + validHost = new ProvisionedHost( + hostname:TEST_HOSTNAME, + displayName:TEST_HOSTNAME, + distro:'RHEL-ALT-7.5', + variant:'Server' + ) invalidHost = new ProvisionedHost() config = new ProvisioningConfig() script = new PipelineTestScript(node:node, sh:sh) @@ -85,9 +94,50 @@ class UtilsTest { assert(script.testLog.contains(INSTALLED)) } + @Test + void shouldntInstallRhpkgOnInvalidProvisionedHost() { + assert(!validHost.rhpkgInstalled) + + ProvisionedHost noDistro = new ProvisionedHost(validHost) + noDistro.distro = '' + Utils.installRhpkg(script, config, noDistro) + assert(!noDistro.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + + ProvisionedHost noVariant = new ProvisionedHost(validHost) + noVariant.variant = '' + Utils.installRhpkg(script, config, noVariant) + assert(!noVariant.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + + ProvisionedHost invalidDistro = new ProvisionedHost(validHost) + invalidDistro.distro = 'CentOS' + Utils.installRhpkg(script, config, invalidDistro) + assert(!invalidDistro.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + + ProvisionedHost noMajorVersion = new ProvisionedHost(validHost) + noMajorVersion.distro = 'RHEL' + Utils.installRhpkg(script, config, noMajorVersion) + assert(!noMajorVersion.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + + ProvisionedHost majorVersionTooLow = new ProvisionedHost(validHost) + majorVersionTooLow.distro = 'RHEL-4' + Utils.installRhpkg(script, config, majorVersionTooLow) + assert(!majorVersionTooLow.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + + ProvisionedHost majorVersionTooHigh = new ProvisionedHost(validHost) + majorVersionTooHigh.distro = 'RHEL-72.0' + Utils.installRhpkg(script, config, majorVersionTooHigh) + assert(!majorVersionTooHigh.rhpkgInstalled) + assert(!script.testLog.contains(INSTALLED)) + } + @Test void genericInstallShouldntWrapNullHost() { - Utils.genericInstall(script, config, null, genericInstall) + Utils.genericInstall(script, config, null, installWrapper) assert(script.testLog.contains(INSTALLED)) assert(!script.testLog.contains(NODE_STEP)) } @@ -97,7 +147,7 @@ class UtilsTest { config.mode = Mode.SSH Boolean exceptionOccured = false try { - Utils.genericInstall(script, config, invalidHost, genericInstall) + Utils.genericInstall(script, config, invalidHost, installWrapper) } catch (e) { exceptionOccured = true } @@ -109,7 +159,7 @@ class UtilsTest { config.mode = Mode.JNLP Boolean exceptionOccured = false try { - Utils.genericInstall(script, config, invalidHost, genericInstall) + Utils.genericInstall(script, config, invalidHost, installWrapper) } catch (e) { exceptionOccured = true } @@ -119,7 +169,7 @@ class UtilsTest { @Test void genericInstallShouldntWrapNamedHostInSSHMode() { config.mode = Mode.SSH - Utils.genericInstall(script, config, validHost, genericInstall) + Utils.genericInstall(script, config, validHost, installWrapper) assert(script.testLog.contains(INSTALLED)) assert(!script.testLog.contains(NODE_STEP)) } @@ -127,7 +177,7 @@ class UtilsTest { @Test void genericInstallShouldWrapNamedHostInJNLPMode() { config.mode = Mode.JNLP - Utils.genericInstall(script, config, validHost, genericInstall) + Utils.genericInstall(script, config, validHost, installWrapper) assert(script.testLog.contains(INSTALLED)) assert(script.testLog.contains(NODE_STEP)) assert(script.testLog.contains(TEST_HOSTNAME)) @@ -136,8 +186,25 @@ class UtilsTest { @Test void genericInstallNotARealMode() { config.mode = 'FAKE' - Utils.genericInstall(script, config, validHost, genericInstall) + Utils.genericInstall(script, config, validHost, installWrapper) assert(!script.testLog.contains(INSTALLED)) assert(!script.testLog.contains(NODE_STEP)) } + + @Test + void noSudoInSSHModeAsRoot() { + config.mode = Mode.SSH + Utils.genericInstall(script, config, validHost, installWrapper) + assert(script.testLog.contains(INSTALLED)) + assert(!script.testLog.contains(SUDO)) + } + + @Test + void sudoInSSHModeAsNonRoot() { + config.mode = Mode.SSH + validHost.remoteUser = 'custom' + Utils.genericInstall(script, config, validHost, installWrapper) + assert(script.testLog.contains(INSTALLED)) + assert(script.testLog.contains(SUDO)) + } } diff --git a/test/com/redhat/ci/provisioner/ProvisioningConfigTest.groovy b/test/com/redhat/ci/provisioner/ProvisioningConfigTest.groovy index b07331c..67720ae 100644 --- a/test/com/redhat/ci/provisioner/ProvisioningConfigTest.groovy +++ b/test/com/redhat/ci/provisioner/ProvisioningConfigTest.groovy @@ -12,6 +12,8 @@ class ProvisioningConfigTest { private static final String SSH_PRIV_KEY_CREDENTIAL_ID_DEFAULT = 'test-sshprivkey' private static final String SSH_PUB_KEY_CREDENTIAL_ID_DEFAULT = 'test-sshpubkey' private static final String JENKINS_SLAVE_CREDENTIAL_ID_DEFAULT = 'test-jenkins-slave-credentials' + private static final String PROVISIONING_REPO_URL_DEFAULT = 'test-repo' + private static final String PROVISIONING_REPO_REF_DEFAULT = 'test-ref' @Test void should_support_legacy_api() { @@ -41,6 +43,8 @@ class ProvisioningConfigTest { assert(config.jenkinsSlaveCredentialId == ProvisioningConfig.JENKINS_SLAVE_CREDENTIAL_ID_DEFAULT) assert(config.jenkinsMasterUrl == ProvisioningConfig.JENKINS_MASTER_URL_DEFAULT) assert(config.jswarmExtraArgs == ProvisioningConfig.JSWARM_EXTRA_ARGS_DEFAULT) + assert(config.provisioningRepoUrl == ProvisioningConfig.PROVISIONING_REPO_URL_DEFAULT) + assert(config.provisioningRepoRef == ProvisioningConfig.PROVISIONING_REPO_REF_DEFAULT) } @Test @@ -52,6 +56,8 @@ class ProvisioningConfigTest { script.params.SSHPRIVKEYCREDENTIALID = SSH_PRIV_KEY_CREDENTIAL_ID_DEFAULT script.params.SSHPUBKEYCREDENTIALID = SSH_PUB_KEY_CREDENTIAL_ID_DEFAULT script.params.JENKINSSLAVECREDENTIALID = JENKINS_SLAVE_CREDENTIAL_ID_DEFAULT + script.params.LIBRARIES_REPO = PROVISIONING_REPO_URL_DEFAULT + script.params.LIBRARIES_REF = PROVISIONING_REPO_REF_DEFAULT ProvisioningConfig config = new ProvisioningConfig(script.params, script.env) assert(config.krbPrincipalCredentialId == KRB_PRINCIPAL_CREDENTIAL_ID_DEFAULT) @@ -61,5 +67,7 @@ class ProvisioningConfigTest { assert(config.jenkinsSlaveCredentialId == JENKINS_SLAVE_CREDENTIAL_ID_DEFAULT) assert(config.jenkinsMasterUrl == PipelineTestScript.JENKINS_MASTER_URL_DEFAULT) assert(config.jswarmExtraArgs == PipelineTestScript.JSWARM_EXTRA_ARGS_DEFAULT) + assert(config.provisioningRepoUrl == PROVISIONING_REPO_URL_DEFAULT) + assert(config.provisioningRepoRef == PROVISIONING_REPO_REF_DEFAULT) } } diff --git a/test/com/redhat/ci/provisioners/LinchPinProvisionerTest.groovy b/test/com/redhat/ci/provisioners/LinchPinProvisionerTest.groovy index 5282a67..f717045 100644 --- a/test/com/redhat/ci/provisioners/LinchPinProvisionerTest.groovy +++ b/test/com/redhat/ci/provisioners/LinchPinProvisionerTest.groovy @@ -66,7 +66,8 @@ class LinchPinProvisionerTest { } ProvisionedHost host = provisioner.provision( - new TargetHost(bkrJobGroup:'maqe', bkrHostRequires:[[tag:'hypervisor', value:'', op:'=']]), + new TargetHost(bkrJobGroup:'maqe', bkrHostRequires:[[tag:'hypervisor', value:'', op:'=']], + variant:'workstation', distro:'RHEL-7.6'), config) assert(!host.error) } diff --git a/test/com/redhat/ci/provisioners/NoOpProvisionerTest.groovy b/test/com/redhat/ci/provisioners/NoOpProvisionerTest.groovy index b34c8cd..4f0f357 100644 --- a/test/com/redhat/ci/provisioners/NoOpProvisionerTest.groovy +++ b/test/com/redhat/ci/provisioners/NoOpProvisionerTest.groovy @@ -92,7 +92,12 @@ class NoOpProvisionerTest { config.installCredentials = true config.installRhpkg = true - ProvisionedHost host = provisioner.provision(new TargetHost(hostname:TEST_HOSTNAME, arch:X86_64), config) + ProvisionedHost host = provisioner.provision( + new TargetHost( + hostname:TEST_HOSTNAME, + arch:X86_64, + inventoryVars:[ ansible_python_interpreter:'/usr/libexec/platform-python' ] + ), config) assert(!host.error) } } diff --git a/vars/getCIMessage.groovy b/vars/getCIMessage.groovy new file mode 100644 index 0000000..37b3990 --- /dev/null +++ b/vars/getCIMessage.groovy @@ -0,0 +1,9 @@ +Map call(String message) { + if (!message) { + return [:] + } + + final String CI_MESSAGE_FILE = 'message.json' + writeFile(file:CI_MESSAGE_FILE, text:message) + readJSON(file:CI_MESSAGE_FILE) +} diff --git a/vars/runTests.groovy b/vars/runTests.groovy index 9a382b7..5329501 100644 --- a/vars/runTests.groovy +++ b/vars/runTests.groovy @@ -38,34 +38,59 @@ void call(ProvisioningConfig config, ProvisionedHost host) { } // Run Scripts try { - String runScriptsPath = 'run_scripts.yml' - String runScripts = libraryResource(runScriptsPath) - writeFile(file:runScriptsPath, text:runScripts) + String runScriptsPlaybook = 'run_scripts.yml' + String runScripts = libraryResource("playbooks/${runScriptsPlaybook}") + writeFile(file:runScriptsPlaybook, text:runScripts) sh(""" ${ACTIVATE_PROVISIONER} ansible-playbook -i '${host.inventoryPath}' --key-file "~/.ssh/id_rsa" \ -e '{"test_dir":"${params.TEST_DIR}", "script_params":"${host.scriptParams ?: ''}"}' \ - ${runScriptsPath} + ${runScriptsPlaybook} """) } catch (e) { exceptions.add(e) } // Collect Artifacts try { - String collectResultsPath = 'collect_results.yml' - String collectResults = libraryResource(collectResultsPath) - writeFile(file:collectResultsPath, text:collectResults) + String collectResultsPlaybook = 'collect_results.yml' + String collectResults = libraryResource("playbooks/${collectResultsPlaybook}") + writeFile(file:collectResultsPlaybook, text:collectResults) sh(""" ${ACTIVATE_PROVISIONER} ansible-playbook -i '${host.inventoryPath}' --key-file "~/.ssh/id_rsa" \ -e '{"test_dir":"${params.TEST_DIR}"}' \ - ${collectResultsPath} + ${collectResultsPlaybook} """) } catch (e) { exceptions.add(e) } } + try { + archiveArtifacts( + allowEmptyArchive:true, + artifacts:"${params.TEST_DIR}/ansible-playbooks/**/artifacts/**/*.*", + fingerprint:true + ) + junit "${params.TEST_DIR}/ansible-playbooks/**/reports/**/*.xml" + } + catch (e) { + // We don't care if this step fails + echo("Ignoring exception: ${e}") + } + try { + archiveArtifacts( + allowEmptyArchive:true, + artifacts:"${params.TEST_DIR}/scripts/**/artifacts/**/*.*", + fingerprint:true + ) + junit "${params.TEST_DIR}/scripts/**/reports/**/*.xml" + } + catch (e) { + // We don't care if this step fails + echo("Ignoring exception: ${e}") + } + exceptions.each { e -> error(e.message) diff --git a/workspace/PinFile b/workspace/PinFile index 504f770..3f24387 100644 --- a/workspace/PinFile +++ b/workspace/PinFile @@ -39,6 +39,12 @@ beaker-slave: {% endif %} layout: inventory_layout: + {% if inventory_vars %} + vars: + {% for key, value in inventory_vars.items() %} + {{ key }}: "{{ value }}" + {% endfor %} + {% endif %} hosts: beaker-slave: count: 1