OpenNebula XML-RPC API client
This commit is contained in:
parent
30d1bed8a5
commit
3173bf5db3
|
@ -0,0 +1,181 @@
|
|||
@Grab('org.codehaus.groovy:groovy-xmlrpc:0.8')
|
||||
import groovy.net.xmlrpc.*
|
||||
import groovy.util.XmlSlurper
|
||||
import groovy.util.slurpersupport.GPathResult
|
||||
import groovy.util.slurpersupport.NodeChild
|
||||
import groovy.xml.XmlUtil
|
||||
|
||||
class Client {
|
||||
|
||||
String oneAuth
|
||||
String url
|
||||
Script script
|
||||
|
||||
// Voir http://groovy-lang.org/processing-xml.html pour plus d'informations
|
||||
// sur le traitement du XML en Groovy
|
||||
|
||||
// OpenNebula RPC API
|
||||
|
||||
@NonCPS
|
||||
XMLRPCServerProxy createProxy() {
|
||||
return new XMLRPCServerProxy(url, true)
|
||||
}
|
||||
|
||||
// Voir https://docs.opennebula.org/5.6/integration/system_interfaces/api.html#one-templatepool-info
|
||||
@NonCPS
|
||||
GPathResult templatepoolInfo(int filter = -2, int start = -1, int end = -1) {
|
||||
def proxy = createProxy()
|
||||
def results = proxy."one.templatepool.info"(oneAuth, filter, start, end)
|
||||
assert results[0] : results[1]
|
||||
return new XmlSlurper().parseText(results[1])
|
||||
}
|
||||
|
||||
|
||||
// Voir https://docs.opennebula.org/5.6/integration/system_interfaces/api.html#one-vm-allocate
|
||||
@NonCPS
|
||||
Integer vmAllocate(String template, Boolean hold = false) {
|
||||
def proxy = createProxy()
|
||||
def results = proxy."one.vm.allocate"(oneAuth, template, hold)
|
||||
assert results[0] : results[1]
|
||||
return results[1]
|
||||
}
|
||||
|
||||
// Voir https://docs.opennebula.org/5.6/integration/system_interfaces/api.html#one-vm-action
|
||||
@NonCPS
|
||||
Integer vmAction(String actionName, Integer objectId) {
|
||||
def proxy = createProxy()
|
||||
def results = proxy."one.vm.action"(oneAuth, actionName, objectId)
|
||||
assert results[0] : results[1]
|
||||
return results[1]
|
||||
}
|
||||
|
||||
// Voir https://docs.opennebula.org/5.6/integration/system_interfaces/api.html#one-vm-info
|
||||
@NonCPS
|
||||
GPathResult vmInfo(Integer objectId) {
|
||||
def proxy = createProxy()
|
||||
def results = proxy."one.vm.info"(oneAuth, objectId)
|
||||
assert results[0] : results[1]
|
||||
return new XmlSlurper().parseText(results[1])
|
||||
}
|
||||
|
||||
// Utilitaires de haut niveau pour les pipelines Jenkins
|
||||
|
||||
// Retrouve un template de VM via son nom
|
||||
@NonCPS
|
||||
NodeChild findVMTemplate(String name) {
|
||||
def templates = templatepoolInfo()
|
||||
def result = null
|
||||
templates.'*'.each {
|
||||
if (it.NAME.text().trim() == name) {
|
||||
result = it
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Démarre une VM, exécute les étapes passées en paramètres
|
||||
// puis supprime la VM
|
||||
@NonCPS
|
||||
void withNewVM(String templateName, Boolean terminateOnExit = true, Closure body) {
|
||||
|
||||
def tmpl = findVMTemplate(templateName)
|
||||
def id = vmAllocate(XmlUtil.serialize(tmpl.TEMPLATE))
|
||||
tmpl = null
|
||||
|
||||
script.println("Démarrage de la VM '${id}'...")
|
||||
|
||||
def info = vmInfo(id)
|
||||
|
||||
script.println("En attente du démarrage de la VM...")
|
||||
while(info.STATE.toInteger() != 3 || info.LCM_STATE.toInteger() != 3) {
|
||||
sleep(5000)
|
||||
info = vmInfo(id)
|
||||
}
|
||||
|
||||
script.println("VM démarrée.")
|
||||
|
||||
def ip = info.TEMPLATE.NIC.IP.text()
|
||||
info = null
|
||||
|
||||
runThenTerminate(id, ip, terminateOnExit, body)
|
||||
|
||||
}
|
||||
|
||||
void runThenTerminate(Integer id, String ip, Boolean terminateOnExit, Closure body) {
|
||||
try {
|
||||
body(ip)
|
||||
} finally {
|
||||
if (terminateOnExit) {
|
||||
script.println("Suppression de la VM '${id}'...")
|
||||
vmAction("terminate", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
def init(String url, String username, String password, Closure body) {
|
||||
def oneAuth = "${username}:${password}"
|
||||
def client = new Client(oneAuth: oneAuth, url: url, script: this)
|
||||
proxy = null
|
||||
body.call(client)
|
||||
}
|
||||
|
||||
def initWithCredentials(String urlCredentialsId, String userCredentialsId, Closure body) {
|
||||
withCredentials([
|
||||
string(credentialsId: urlCredentialsId, variable: 'NEBULA_URL'),
|
||||
usernamePassword(credentialsId: userCredentialsId, usernameVariable: 'NEBULA_USERNAME', passwordVariable: 'NEBULA_PASSWORD')
|
||||
]) {
|
||||
init(env.NEBULA_URL, env.NEBULA_USERNAME, env.NEBULA_PASSWORD, body)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def runInNewVM(Map args) {
|
||||
|
||||
def urlCredentialsId = args.get('urlCredentialsId', 'opennebula-dev-url')
|
||||
def userCredentialsId = args.get('userCredentialsId', 'kipp-credentials')
|
||||
def sshCredentialsId = args.get('sshCredentialsId', 'kipp-opennebula-dev-ssh-keypair')
|
||||
def vmTemplate = args.get('vmTemplate', '')
|
||||
def terminateOnExit = args.get('terminateOnExit', true)
|
||||
def shell = args.get("shell", "/bin/sh")
|
||||
def script = args.get('script', '')
|
||||
|
||||
// On récupère les identifiants de connexion SSH pour la VM
|
||||
withCredentials([
|
||||
sshUserPrivateKey(credentialsId: sshCredentialsId, keyFileVariable: 'VM_SSH_KEY')
|
||||
]) {
|
||||
initWithCredentials(urlCredentialsId, userCredentialsId) { client ->
|
||||
client.withNewVM(vmTemplate, terminateOnExit) { host ->
|
||||
|
||||
def sshArgs = "-i ${VM_SSH_KEY} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||
|
||||
// On attend que la connexion SSH soit disponible
|
||||
println "En attente de l'accès SSH..."
|
||||
waitUntil {
|
||||
try {
|
||||
sh "ssh -q ${sshArgs} -o ConnectTimeout=1 root@${host} exit"
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// On créait un script temporaire à exécuter sur la machine distante
|
||||
def now = System.currentTimeMillis()
|
||||
def tempScriptFile = "script_${env.BUILD_ID}_${now}.sh"
|
||||
writeFile(file: tempScriptFile, text: """
|
||||
#!${shell}
|
||||
${script.stripIndent()}
|
||||
""")
|
||||
|
||||
// On transfère le script sur la machine distante et on l'exécute
|
||||
sh """
|
||||
scp ${sshArgs} '${tempScriptFile}' 'root@${host}:/tmp/${tempScriptFile}'
|
||||
ssh ${sshArgs} root@${host} 'chmod +x /tmp/${tempScriptFile}; /tmp/${tempScriptFile}'
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue