Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Commit

Permalink
Support for rhpkg install on SSH mode. (#23)
Browse files Browse the repository at this point in the history
* Support for install scripts running in SSH mode

* Shell command now attempts to ssh before installing RHPKG

* Added optional param for sudo

* Removed sshcommand

* Install brew pkgs should accept sudo params now

* Since this is a public method, I'm restricting the API to privileged or not

* Looked down privileged API

* Using writeFile to ensure that file in run as input

* writeFile apparently expects map args
  • Loading branch information
jaypoulz authored Oct 4, 2018
1 parent 9cb2a7b commit e9da07b
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 79 deletions.
126 changes: 81 additions & 45 deletions src/com/redhat/ci/Utils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,47 @@ package com.redhat.ci

import com.redhat.ci.hosts.ProvisionedHost
import com.redhat.ci.provisioner.ProvisioningConfig
import com.redhat.ci.provisioner.ProvisioningException
import com.redhat.ci.provisioner.Mode

/**
* Utility class to perform actions upon CI hosts.
*/
class Utils {
private static final String SUDO = 'sudo'
private static final String NO_SUDO = ''
private static final String INSTALL_FILE = 'install.sh'

/**
* Attemps to install Ansible.
*/
@SuppressWarnings('GStringExpressionWithinString')
static void installAnsible(Script script, ProvisionedHost host = null) {
installWrapper(script, host) {
h ->
script.sh '''
sudo yum install python-devel openssl-devel libffi-devel -y &&
sudo mkdir -p /home/jenkins &&
sudo chown --recursive ${USER}:${USER} /home/jenkins &&
sudo pip install --upgrade pip &&
sudo pip install --upgrade setuptools &&
sudo pip install --upgrade ansible
'''
if (h == null) {
static void installAnsible(Script script, ProvisioningConfig config, ProvisionedHost host = null) {
genericInstall(script, config, host) {
privileged, sh ->
String sudo = privileged ? SUDO : NO_SUDO
sh("""
${sudo} yum install python-devel openssl-devel libffi-devel -y &&
${sudo} mkdir -p /home/jenkins &&
${sudo} chown --recursive \${USER}:\${USER} /home/jenkins &&
${sudo} pip install --upgrade pip &&
${sudo} pip install --upgrade setuptools &&
${sudo} pip install --upgrade ansible
""")
if (host == null) {
return
}
h.ansibleInstalled = true
host.ansibleInstalled = true
}
}

/**
* Attempts to install SSH and Beaker credentials.
*/
static void installCredentials(Script script, ProvisioningConfig config, ProvisionedHost host = null) {
installWrapper(script, host) {
h ->
genericInstall(script, config, host) {
privileged, sh ->
String sudo = privileged ? SUDO : NO_SUDO
script.withCredentials([
script.file(credentialsId:config.keytabCredentialId, variable:'KEYTAB'),
script.usernamePassword(credentialsId:config.krbPrincipalCredentialId,
Expand All @@ -46,14 +54,13 @@ class Utils {
script.file(credentialsId:config.bkrConfCredentialId, variable:'BKRCONF'),
]) {
script.env.HOME = '/home/jenkins'
script.sh """
sudo yum install -y krb5-workstation || yum install -y krb5-workstation
sudo cp ${script.KRBCONF} /etc/krb5.conf || cp ${script.KRBCONF} /etc/krb5.conf
sudo mkdir -p /etc/beaker || mkdir -p /etc/beaker
sudo cp ${script.BKRCONF} /etc/beaker/client.conf ||
cp ${script.BKRCONF} /etc/beaker/client.conf
sudo chmod 644 /etc/krb5.conf || chmod 644 /etc/krb5.conf
sudo chmod 644 /etc/beaker/client.conf || chmod 644 /etc/beaker/client.conf
sh("""
${sudo} yum install -y krb5-workstation
${sudo} cp ${script.KRBCONF} /etc/krb5.conf
${sudo} mkdir -p /etc/beaker
${sudo} cp ${script.BKRCONF} /etc/beaker/client.conf
${sudo} chmod 644 /etc/krb5.conf
${sudo} chmod 644 /etc/beaker/client.conf
kinit ${script.KRB_PRINCIPAL} -k -t ${script.KEYTAB}
mkdir -p ~/.ssh
cp ${script.SSHPRIVKEY} ~/.ssh/id_rsa
Expand All @@ -62,9 +69,9 @@ class Utils {
chmod 644 ~/.ssh/id_rsa.pub
eval "\$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
"""
if (h != null) {
h.credentialsInstalled = true
""")
if (host != null) {
host.credentialsInstalled = true
}
}
}
Expand All @@ -74,23 +81,24 @@ class Utils {
* Attempts to install and configure the RHPKG tool.
*/
@SuppressWarnings('LineLength')
static void installRhpkg(Script script, ProvisionedHost host = null) {
installWrapper(script, host) {
h ->
script.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
static void installRhpkg(Script script, ProvisioningConfig config, ProvisionedHost host = null) {
genericInstall(script, config, host) {
privileged, sh ->
String sudo = privileged ? SUDO : NO_SUDO
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
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 yum install -y yum-utils git
${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
sudo yum install -y rhpkg
${sudo} yum-config-manager --add-repo rcm-tools-rhel-7-server.repo
${sudo} yum install -y rhpkg
git config --global user.name "jenkins"
'''
if (h != null) {
h.rhpkgInstalled = true
""")
if (host != null) {
host.rhpkgInstalled = true
}
}
}
Expand All @@ -100,16 +108,44 @@ class Utils {
* If a provisioned host with a non-null displayName is passed in, the install step will be
* attempted on that host; otherwise, the install with target the current node.
*/
static void installWrapper(Script script, ProvisionedHost host, Closure install) {
static void genericInstall(Script script, ProvisioningConfig config, ProvisionedHost host, Closure installWrapper) {
// Installation should occur on current node
if (host == null || host.displayName == null) {
install(host)
if (host == null) {
installWrapper(NO_SUDO) {
shCommand ->
script.sh(shCommand)
}
return
}

// Installation should occur on target host (JNLP)
if (config.mode == Mode.JNLP) {
if (!host.displayName) {
throw new ProvisioningException('Installing in SSH mode but displayName is invalid.')
}

script.node(host.displayName) {
installWrapper(SUDO) {
shCommand ->
script.sh(shCommand)
}
}
return
}

// Installation should occur on target host
script.node(host.displayName) {
install(host)
// Installation should occur on target host (SSH)
if (config.mode == Mode.SSH) {
if (!host.hostname) {
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)
}
}
}
}
4 changes: 2 additions & 2 deletions src/com/redhat/ci/provisioners/LinchPinProvisioner.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class LinchPinProvisioner extends AbstractProvisioner {
// In JNLP mode, we can install Ansible so the user can run playbooks
// (Already installed in SSH mode)
if (config.installAnsible) {
Utils.installAnsible(script, host)
Utils.installAnsible(script, config, host)
}

// In JNLP mode, install provisioning credentials directly on the provisioned host
Expand All @@ -98,7 +98,7 @@ class LinchPinProvisioner extends AbstractProvisioner {

// We can install the RHPKG tool if the user intends to use it.
if (config.installRhpkg) {
Utils.installRhpkg(script, host)
Utils.installRhpkg(script, config, host)
}
} catch (e) {
script.echo("Exception: ${e.message}")
Expand Down
5 changes: 5 additions & 0 deletions test/PipelineTestScript.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ class PipelineTestScript extends Script {
body()
}

Closure writeFile = {
args ->
LOG.info("writeFile(${args})")
}

PipelineTestScript() {
binding.with {
currentBuild = [
Expand Down
72 changes: 50 additions & 22 deletions test/com/redhat/ci/UtilsTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.junit.Test
import org.junit.Before
import com.redhat.ci.hosts.ProvisionedHost
import com.redhat.ci.provisioner.ProvisioningConfig
import com.redhat.ci.provisioner.Mode

/**
* Tests the install script wrapper.
Expand All @@ -12,13 +13,14 @@ class UtilsTest {
private static final String INSTALLED = 'Installed'
private static final String TEST_HOSTNAME = 'test-host'
private static final String NODE_STEP = 'node'
private ProvisionedHost host = null
private ProvisionedHost validHost = null
private ProvisionedHost invalidHost = null
private ProvisioningConfig config = null
private PipelineTestScript script = null

private final Closure genericInstall = {
host ->
script.sh(INSTALLED)
sudo, sh ->
sh(INSTALLED)
}

private final Closure node = {
Expand All @@ -35,30 +37,31 @@ class UtilsTest {

@Before
void init() {
host = new ProvisionedHost()
validHost = new ProvisionedHost(hostname:TEST_HOSTNAME, displayName:TEST_HOSTNAME)
invalidHost = new ProvisionedHost()
config = new ProvisioningConfig()
script = new PipelineTestScript(node:node, sh:sh)
}

@Test
void shouldInstallAnsibleOnProvisionedHost() {
assert(host.ansibleInstalled == false)
Utils.installAnsible(script, host)
assert(host.ansibleInstalled == true)
assert(validHost.ansibleInstalled == false)
Utils.installAnsible(script, config, validHost)
assert(validHost.ansibleInstalled == true)
assert(script.testLog.contains(INSTALLED))
}

@Test
void shouldInstallAnsibleOnCurrentHost() {
Utils.installAnsible(script)
Utils.installAnsible(script, config)
assert(script.testLog.contains(INSTALLED))
}

@Test
void shouldInstallCredentialsOnProvisionedHost() {
assert(host.credentialsInstalled == false)
Utils.installCredentials(script, config, host)
assert(host.credentialsInstalled == true)
assert(validHost.credentialsInstalled == false)
Utils.installCredentials(script, config, validHost)
assert(validHost.credentialsInstalled == true)
assert(script.testLog.contains(INSTALLED))
}

Expand All @@ -70,36 +73,61 @@ class UtilsTest {

@Test
void shouldInstallRhpkgOnProvisionedHost() {
assert(host.rhpkgInstalled == false)
Utils.installRhpkg(script, host)
assert(host.rhpkgInstalled == true)
assert(validHost.rhpkgInstalled == false)
Utils.installRhpkg(script, config, validHost)
assert(validHost.rhpkgInstalled == true)
assert(script.testLog.contains(INSTALLED))
}

@Test
void shouldInstallRhpkgOnCurrentHost() {
Utils.installRhpkg(script)
Utils.installRhpkg(script, config)
assert(script.testLog.contains(INSTALLED))
}

@Test
void installWrapperShouldntWrapNullHost() {
Utils.installWrapper(script, null, genericInstall)
void genericInstallShouldntWrapNullHost() {
Utils.genericInstall(script, config, null, genericInstall)
assert(script.testLog.contains(INSTALLED))
assert(!script.testLog.contains(NODE_STEP))
}

@Test
void installWrapperShouldntWrapNamelessHost() {
Utils.installWrapper(script, host, genericInstall)
void genericInstallShouldntInstallOnNamelessHostInSSHMode() {
config.mode = Mode.SSH
Boolean exceptionOccured = false
try {
Utils.genericInstall(script, config, invalidHost, genericInstall)
} catch (e) {
exceptionOccured = true
}
assert(exceptionOccured)
}

@Test
void genericInstallShouldntInstallOnNamelessHostInJNLPMode() {
config.mode = Mode.JNLP
Boolean exceptionOccured = false
try {
Utils.genericInstall(script, config, invalidHost, genericInstall)
} catch (e) {
exceptionOccured = true
}
assert(exceptionOccured)
}

@Test
void genericInstallShouldntWrapNamedHostInSSHMode() {
config.mode = Mode.SSH
Utils.genericInstall(script, config, validHost, genericInstall)
assert(script.testLog.contains(INSTALLED))
assert(!script.testLog.contains(NODE_STEP))
}

@Test
void installWrapperShouldWrapNamedHost() {
host.displayName = TEST_HOSTNAME
Utils.installWrapper(script, host, genericInstall)
void genericInstallShouldWrapNamedHostInJNLPMode() {
config.mode = Mode.JNLP
Utils.genericInstall(script, config, validHost, genericInstall)
assert(script.testLog.contains(INSTALLED))
assert(script.testLog.contains(NODE_STEP))
assert(script.testLog.contains(TEST_HOSTNAME))
Expand Down
20 changes: 10 additions & 10 deletions vars/installBrewPkgs.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@SuppressWarnings('GStringExpressionWithinString')
void call(Map params) {
void call(Map params, Boolean privileged = false) {
String sudo = privileged ? 'sudo' : ''
Boolean taskRepoCreated = false
if (params.CI_MESSAGE != '') {
tid = getTaskId(params.CI_MESSAGE)
Expand All @@ -11,14 +11,14 @@ void call(Map params) {
}

if (taskRepoCreated == true) {
sh '''
sudo yum install -y yum-utils
sh """
${sudo} yum install -y yum-utils
URL=\$(cat task-repo.properties | grep TASK_REPO_URLS= | sed 's/TASK_REPO_URLS=//' | sed 's/;/\\n/g')
sudo yum-config-manager --add-repo \${URL}
sudo cat /etc/yum.repos.d/*download.eng.bos.redhat.com*
sudo sed -i 's/gpgcheck=1/gpgcheck=0/g' /etc/yum.repos.d/*download.eng.bos.redhat.com*
echo "gpgcheck=0" | sudo tee -a /etc/yum.repos.d/*download.eng.bos.redhat.com*
sudo yum clean all
'''
${sudo} yum-config-manager --add-repo \${URL}
${sudo} cat /etc/yum.repos.d/*download.eng.bos.redhat.com*
${sudo} sed -i 's/gpgcheck=1/gpgcheck=0/g' /etc/yum.repos.d/*download.eng.bos.redhat.com*
echo "gpgcheck=0" | ${sudo} tee -a /etc/yum.repos.d/*download.eng.bos.redhat.com*
${sudo} yum clean all
"""
}
}

0 comments on commit e9da07b

Please sign in to comment.