I've been setting up the official Jenkins docker container in my lab, and I'm installing Ansible (and also Python if possible) as plugins.
I've installed the Ansible plugin and I need to setup/install the binary. I'm trying to utilise the functionality to "Install plugin via script" which I think builds and installs at container runtime.
Any idea how I can achieve this?
I have seen many guides for rebuilding the container with Ansible installed inside, but is there any advice on how to use the function to install Ansible executable via the plugin?
I'm not looking to build a new container.
Well I figured it out. I'm no genius but I'm disappointed that nobody even tried to volunteer an answer, I see that increasingly more on this community, people responding with "WHY do you want to do this? Justify your reason?" rather than simply helping. Much smarter people than me, but eh.
I hope this answer helps someone else.
Anyway, I used the SSH Pipeline Steps Plugin to connect Jenkins to its own Docker host using SSH, and using Docker Exec, tell the Jenkins Container to install Ansible and Python3.
I setup ssh Credentials in [Jenkins] > [Manage Jenkins] > [Manage Credentials] and add them there (I tried Keys but didn't work at first so I'll do that later so this is with user/password).
Next I made sure to have the SSH Pipeline Steps Plugin installed. I also have the Startup Trigger Plugin to set this Pipeline to run at Jenkins startup, so it always runs nicely.
If you edit line 47, you can add more packages than just Ansible.
If you are using the Alpine version of the Jenkins container, be sure to use apk update && apk add ansible
instead of using apt
.
You can also do this directly by running on your docker host:
docker exec --user root Jenkins bash -c "command -v ansible >/dev/null 2>&1 || (apt update && apt install -y ansible)"
but this is Jenkins SO WHY WOULD I NOT AUTOMATE IT.
I setup a new 2-stage Jenkins Pipeline:
//Setup Remote for SSH Pipeline Steps Plugin
def remote = [:]
remote.name = "dockerhost"
remote.host = "dockerhost.local"
remote.allowAnyHosts = true
pipeline {
agent any
environment {
//Declare Credentials for Remote
SERVER_CREDS=credentials('dockerhost-ssh-pw')
}
stages {
stage('Check Ansible Installation') {
steps {
script {
//credentials for SSH Pipeline Steps Plugin
remote.user=env.SERVER_CREDS_USR
remote.password=env.SERVER_CREDS_PSW
//check if ansible is installed
echo "Checking if Ansible is installed on Jenkins..."
//check is marked to always return true, otherwise will stop pipeline
def response1 = sshCommand remote: remote, command: "docker exec --user root Jenkins which ansible || true"
// Store response1 in a global variable for later use
currentBuild.description = response1.trim()
echo "Response from Jenkins: ${response1}"
}
}
}
stage('Installation State') {
steps {
script {
//credentials for SSH Pipeline Steps Plugin
remote.user=env.SERVER_CREDS_USR
remote.password=env.SERVER_CREDS_PSW
// Use the output from the first stage
def stage1Response = currentBuild.description
echo "If empty, not installed: ${stage1Response}"
// Conditional logic based on response
if (stage1Response == "/usr/bin/ansible") {
echo "Ansible is installed!"
} else {
echo "Unexpected response! Installing Ansible!"
def response2 = sshCommand remote: remote, command: 'docker exec --user root Jenkins bash -c "command -v ansible >/dev/null 2>&1 || (apt update && apt install -y ansible)"'
}
echo "Ansible Installed!"
}
}
}
}
}
If this helped you, an upvote is appreciated. 👌