blob: b4832706cabb9d3d35773cda1d4fc009a7fed2bc [file] [log] [blame]
Filip Pytloun0a07f702017-02-24 18:26:18 +01001/**
2 *
3 * Launch heat stack with CI/CD lab infrastructure
4 *
5 * Expected parameters:
6 * HEAT_TEMPLATE_URL URL to git repo with Heat templates
7 * HEAT_TEMPLATE_CREDENTIALS Credentials to the Heat templates repo
8 * HEAT_TEMPLATE_BRANCH Heat templates repo branch
9 * HEAT_STACK_NAME Heat stack name
10 * HEAT_STACK_TEMPLATE Heat stack HOT template
11 * HEAT_STACK_ENVIRONMENT Heat stack environmental parameters
12 * HEAT_STACK_ZONE Heat stack availability zone
13 * HEAT_STACK_PUBLIC_NET Heat stack floating IP pool
14 * HEAT_STACK_DELETE Delete Heat stack when finished (bool)
15 * HEAT_STACK_CLEANUP_JOB Name of job for deleting Heat stack
16 * HEAT_STACK_REUSE Reuse Heat stack (don't create one)
17 *
18 * SALT_MASTER_CREDENTIALS Credentials to the Salt API
Filip Pytloune32fda82017-02-24 18:26:18 +010019 * SALT_MASTER_PORT Port of salt-api, defaults to 8000
Filip Pytloun0a07f702017-02-24 18:26:18 +010020 *
21 * OPENSTACK_API_URL OpenStack API address
22 * OPENSTACK_API_CREDENTIALS Credentials to the OpenStack API
23 * OPENSTACK_API_PROJECT OpenStack project to connect to
24 * OPENSTACK_API_CLIENT Versions of OpenStack python clients
25 * OPENSTACK_API_VERSION Version of the OpenStack API (2/3)
26 *
27 */
28
29git = new com.mirantis.mk.Git()
30openstack = new com.mirantis.mk.Openstack()
31salt = new com.mirantis.mk.Salt()
32orchestrate = new com.mirantis.mk.Orchestrate()
33
34node {
35
36 // connection objects
37 def openstackCloud
38 def saltMaster
39
40 // value defaults
41 def openstackVersion = OPENSTACK_API_CLIENT ? OPENSTACK_API_CLIENT : 'liberty'
42 def openstackEnv = "${env.WORKSPACE}/venv"
43
44 if (HEAT_STACK_NAME == '') {
45 HEAT_STACK_NAME = BUILD_TAG
46 }
47
48 //
49 // Bootstrap
50 //
51
52 stage ('Download Heat templates') {
53 git.checkoutGitRepository('template', HEAT_TEMPLATE_URL, HEAT_TEMPLATE_BRANCH, HEAT_TEMPLATE_CREDENTIALS)
54 }
55
56 stage('Install OpenStack CLI') {
57 openstack.setupOpenstackVirtualenv(openstackEnv, openstackVersion)
58 }
59
60 stage('Connect to OpenStack cloud') {
61 openstackCloud = openstack.createOpenstackEnv(OPENSTACK_API_URL, OPENSTACK_API_CREDENTIALS, OPENSTACK_API_PROJECT)
62 openstack.getKeystoneToken(openstackCloud, openstackEnv)
63 }
64
65 if (HEAT_STACK_REUSE == 'false') {
66 stage('Launch new Heat stack') {
67 envParams = [
68 'instance_zone': HEAT_STACK_ZONE,
69 'public_net': HEAT_STACK_PUBLIC_NET
70 ]
71 openstack.createHeatStack(openstackCloud, HEAT_STACK_NAME, HEAT_STACK_TEMPLATE, envParams, HEAT_STACK_ENVIRONMENT, openstackEnv)
72 }
73 }
74
75 stage('Connect to Salt master') {
Filip Pytloune32fda82017-02-24 18:26:18 +010076 def saltMasterPort
77 try {
78 saltMasterPort = SALT_MASTER_PORT
79 } catch (MissingPropertyException e) {
80 saltMasterPort = 8000
81 }
Filip Pytloun0a07f702017-02-24 18:26:18 +010082 saltMasterHost = openstack.getHeatStackOutputParam(openstackCloud, HEAT_STACK_NAME, 'salt_master_ip', openstackEnv)
Filip Pytloune32fda82017-02-24 18:26:18 +010083 saltMasterUrl = "http://${saltMasterHost}:${saltMasterPort}"
Filip Pytloun0a07f702017-02-24 18:26:18 +010084 saltMaster = salt.connection(saltMasterUrl, SALT_MASTER_CREDENTIALS)
85 }
86
87 //
88 // Install
89 //
90
91 stage('Install core infra') {
92 // salt.master, reclass
93 // refresh_pillar
94 // sync_all
95 // linux,openssh,salt.minion.ntp
96
97 orchestrate.installFoundationInfra(saltMaster)
98 orchestrate.validateFoundationInfra(saltMaster)
99 }
100
101 stage("Deploy GlusterFS") {
102 salt.runSaltProcessStep(master, 'I@glusterfs:server', 'state.sls', ['glusterfs.server.service'])
103 salt.runSaltProcessStep(master, 'ci01*', 'state.sls', ['glusterfs.server.setup'])
104 salt.runSaltProcessStep(master, 'I@glusterfs:client', 'state.sls', ['glusterfs.client'])
105 }
106
107 stage("Deploy GlusterFS") {
108 salt.runSaltProcessStep(master, 'I@haproxy:proxy', 'state.sls', ['haproxy,keepalived'])
109 }
110
111 stage("Setup Docker Swarm") {
112 salt.runSaltProcessStep(master, 'I@docker:host', 'state.sls', ['docker.host'])
113 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'state.sls', ['docker.swarm'])
114 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'mine.flush')
115 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'mine.update')
116 salt.runSaltProcessStep(master, 'I@docker:swarm', 'state.sls', ['docker.swarm'])
117 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'cmd.run', ['docker node ls'])
118 }
119
120 stage("Deploy Docker services") {
121 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'state.sls', ['docker.client'])
122 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'cmd.run', ['docker service ls'])
123
124 retry(30) {
125 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'cmd.run', ["""/bin/bash -c '! docker service ls | grep -E "0/[0-9]+"'"""])
126 sleep(10)
127 }
128 }
129
130 stage("Configure CI/CD services") {
131 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'state.sls', ['aptly'])
132 retry(2) {
133 // Needs to run twice to pass __virtual__ method of gerrit module
134 // after installation of dependencies
135 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'state.sls', ['gerrit'])
136 }
137 salt.runSaltProcessStep(master, 'I@docker:swarm:role:master', 'state.sls', ['jenkins'])
138 }
139
140 //
141 // Cleanup
142 //
143
144 if (HEAT_STACK_DELETE == 'true') {
145 stage('Trigger cleanup job') {
146 build job: 'deploy_heat_cleanup', parameters: [[$class: 'StringParameterValue', name: 'HEAT_STACK_NAME', value: HEAT_STACK_NAME]]
147 }
148 }
149}