blob: a19b9700920f14f5d7fc8bd0390349bc272080fe [file] [log] [blame]
Martin Polreich4a9f71c2018-10-17 16:40:51 +02001/**
2 * Generate cookiecutter cluster by individual products
3 *
4 * Expected parameters:
5 * COOKIECUTTER_TEMPLATE_CONTEXT Context parameters for the template generation.
6 * SALT_MASTER_URL URL of Salt master
7 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
8 *
9 **/
10
11import static groovy.json.JsonOutput.toJson
12
13common = new com.mirantis.mk.Common()
14python = new com.mirantis.mk.Python()
15salt = new com.mirantis.mk.Salt()
16ssh = new com.mirantis.mk.Ssh()
17
18pepperEnv = "pepperEnv"
19
20slaveNode = env.SLAVE_NODE ?: 'python&&docker'
21model_job = 0
22
23timeout(time: 2, unit: 'HOURS') {
24 node(slaveNode) {
25 try {
26 def templateContext = readYaml text: COOKIECUTTER_TEMPLATE_CONTEXT
27 def clusterName = templateContext.default_context.cluster_name
28 def aioNodeHostname = templateContext.default_context.aio_node_hostname
29 def aioInternalAddress = templateContext.default_context.aio_internal_address
30 def drivetrainInternalAddress = templateContext.default_context.drivetrain_internal_address
31 def artifact_tar_file = "${clusterName}.tar.gz"
Martin Polreich4a9f71c2018-10-17 16:40:51 +020032 def masterIP = templateContext.default_context.drivetrain_external_address
Adam Tenglerc9ed4dc2018-10-31 18:26:28 +010033 if ( templateContext.default_context.get("docker_deployment", "False").toBoolean() ) {
34 masterIP = drivetrainInternalAddress
35 }
Martin Polreich4a9f71c2018-10-17 16:40:51 +020036 def masterUrl = "http://" + masterIP + ":6969"
Martin Polreich4a9f71c2018-10-17 16:40:51 +020037 def outputDirectory = env.WORKSPACE + "/"
Martin Polreich4a9f71c2018-10-17 16:40:51 +020038 def outputDestination = outputDirectory + artifact_tar_file
39 def outputCluster = outputDirectory + "/classes/cluster/" + clusterName
Adam Tenglerc9ed4dc2018-10-31 18:26:28 +010040 def rsyncLocation = templateContext.default_context.get("rsync_location", "/srv/salt/reclass/classes/cluster")
41 def rsyncCredentials = templateContext.default_context.get("rsync_credentials", "lab")
42 c = common.getSshCredentials(rsyncCredentials)
43 def rsyncSSHKey = c.getPrivateKey()
44 def rsyncUser = c.getUsername()
45 def rsyncKeyFile = outputDirectory + "rsync_key"
46 def rsyncPath = rsyncUser + "@" + masterIP + ":" + rsyncLocation
Martin Polreich4a9f71c2018-10-17 16:40:51 +020047 currentBuild.description = "Cluster " + clusterName + " on " + masterIP
48
49 stage("Generate AIO model") {
50 model_job = build(job: 'generate-salt-model-separated-products',
51 parameters: [
52 [$class: 'StringParameterValue', name: 'COOKIECUTTER_TEMPLATE_CONTEXT', value: COOKIECUTTER_TEMPLATE_CONTEXT ],
53 [$class: 'BooleanParameterValue', name: 'TEST_MODEL', value: false],
54 ])
55 }
56
57 stage("Download artifact with model") {
58 artifact_tar_url = "${env.JENKINS_URL}/job/generate-salt-model-separated-products/${model_job.number}/artifact/output-${clusterName}/${artifact_tar_file}"
59 sh "wget --progress=dot:mega --auth-no-challenge -O ${outputDestination} '${artifact_tar_url}'"
60 sh "tar -xzvf ${outputDestination}"
61 }
62
63 stage("Send model to Salt master node") {
64 ssh.ensureKnownHosts(masterIP)
65 writeFile(file: rsyncKeyFile, text: rsyncSSHKey)
66 sh("chmod 600 ${rsyncKeyFile}")
67 common.infoMsg("Copying cluster model to ${rsyncPath}")
68 sh("rsync -r -e \"ssh -i ${rsyncKeyFile}\" ${outputCluster} ${rsyncPath}")
69 }
70
71 stage("Setup virtualenv for Pepper") {
Ivan Berezovskiy46b7bbc2018-10-30 22:32:13 +040072 python.setupPepperVirtualenv(pepperEnv, masterUrl, SALT_MASTER_CREDENTIALS)
Martin Polreich4a9f71c2018-10-17 16:40:51 +020073 }
74
75 stage("Prepare AIO node"){
76 tgt = "S@" + aioInternalAddress
77 // Classify AIO node
78 eventData = [:]
79 eventData["node_control_ip"] = aioInternalAddress
80 eventData["node_os"] = "xenial"
81 eventData["node_master_ip"] = drivetrainInternalAddress
82 eventData["node_hostname"] = aioNodeHostname
83 eventData["node_cluster"] = clusterName
84 eventJson = toJson(eventData)
85 event = "salt-call event.send \"reclass/minion/classify\" \'" + eventJson + "\'"
86 salt.cmdRun(pepperEnv, tgt, event)
87 sleep(30)
88 // Upgrade Salt minion
89 salt.runSaltProcessStep(pepperEnv, tgt, 'pkg.install', "salt-minion")
90 sleep(10)
91 // Run core states on AIO node
92 salt.fullRefresh(pepperEnv, '*')
93 salt.enforceState(pepperEnv, tgt, 'linux')
94 salt.enforceState(pepperEnv, tgt, 'salt')
95 salt.enforceState(pepperEnv, tgt, 'openssh')
96 salt.enforceState(pepperEnv, tgt, 'ntp')
97 salt.enforceState(pepperEnv, tgt, 'rsyslog')
98 }
99
100 stage("Deploy Openstack") {
101 build(job: 'deploy_openstack',
102 parameters: [
Ivan Berezovskiy46b7bbc2018-10-30 22:32:13 +0400103 [$class: 'StringParameterValue', name: 'SALT_MASTER_CREDENTIALS', value: SALT_MASTER_CREDENTIALS],
Martin Polreich4a9f71c2018-10-17 16:40:51 +0200104 [$class: 'StringParameterValue', name: 'SALT_MASTER_URL', value: masterUrl],
105 [$class: 'StringParameterValue', name: 'STACK_INSTALL', value: 'openstack']
106 ])
107 }
108 } catch (Throwable e) {
109 currentBuild.result = "FAILURE"
110 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
111 throw e
112 } finally {
113 stage('Clean workspace directories') {
114 sh(script: 'find . -mindepth 1 -delete > /dev/null || true')
115 }
116 // common.sendNotification(currentBuild.result,"",["slack"])
117 }
118 }
119}