blob: 348de4987de810f3339b0018cafdf42c5a72f811 [file] [log] [blame]
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +00001/**
2 * Upgrade MySQL and Galera packages on dbs nodes.
3 * Update packages on given nodes
4 *
5 * Expected parameters:
6 * SALT_MASTER_CREDENTIALS Credentials to the Salt API.
7 * SALT_MASTER_URL Full Salt API address [http://10.10.10.15:6969].
8 * SHUTDOWN_CLUSTER Shutdown all mysql instances on target nodes at the same time.
9 * OS_DIST_UPGRADE Upgrade system packages including kernel (apt-get dist-upgrade).
10 * OS_UPGRADE Upgrade all installed applications (apt-get upgrade)
11 * TARGET_SERVERS Comma separated list of salt compound definitions to upgrade.
12 * INTERACTIVE Ask interactive questions during pipeline run (bool).
Roman Lubianyifb10a4d2022-02-11 12:37:46 +020013 * UPDATE_TO_MYSQL57 Set this flag if you are updating MySQL from 5.6 to 5.7
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +000014 *
15**/
16
17def common = new com.mirantis.mk.Common()
18def salt = new com.mirantis.mk.Salt()
19def python = new com.mirantis.mk.Python()
20def debian = new com.mirantis.mk.Debian()
21def openstack = new com.mirantis.mk.Openstack()
22def galera = new com.mirantis.mk.Galera()
23def shutdownCluster = SHUTDOWN_CLUSTER.toBoolean()
24def interactive = INTERACTIVE.toBoolean()
25def LinkedHashMap upgradeStageMap = [:]
Roman Lubianyifb10a4d2022-02-11 12:37:46 +020026def updateToMysql57 = UPDATE_TO_MYSQL57.toBoolean()
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +000027
28upgradeStageMap.put('Pre upgrade',
29 [
30 'Description': 'Only non destructive actions will be applied during this phase. Basic service verification will be performed.',
31 'Status': 'NOT_LAUNCHED',
32 'Expected behaviors': '''
33 * No service downtime
34 * No workload downtime''',
35 'Launched actions': '''
36 * Verify API, perform basic CRUD operations for services.
37 * Verify MySQL is running and Galera cluster is operational.''',
38 'State result': 'Basic checks around wsrep Galera status are passed.'
39 ])
40
41upgradeStageMap.put('Stop MySQL service',
42 [
43 'Description': 'All MySQL services will be stopped on All TARGET_SERVERS nodes.',
44 'Status': 'NOT_LAUNCHED',
45 'Expected behaviors': '''
46 * MySQL services are stopped.
47 * OpenStack APIs are not accessible from this point.
48 * No workload downtime''',
49 'Launched actions': '''
50 * Stop MySQL services''',
51 'State result': 'MySQL service is stopped',
52 ])
53
54upgradeStageMap.put('Upgrade OS',
55 [
56 'Description': 'Optional step. OS packages will be upgraded during this phase, depending on the job parameters dist-upgrade might be called. And reboot of node executed.',
57 'Status': 'NOT_LAUNCHED',
58 'Expected behaviors': '''
59 * No workload downtime
60 * The nodes might be rebooted''',
61 'Launched actions': '''
62 * Install new version of system packages
63 * If doing dist-upgrade new kernel might be installed and node rebooted
64 * System packages are updated
65 * Node might be rebooted
66'''
67 ])
68
69upgradeStageMap.put('Upgrade MySQL server',
70 [
71 'Description': 'MySQL and Erlang code will be upgraded during this stage. No workload downtime is expected.',
72 'Status': 'NOT_LAUNCHED',
73 'Expected behaviors': '''
74 * OpenStack services loose connection to MySQL server
75 * No workload downtime''',
76 'Launched actions': '''
77 * Install new version of MySQL and Galera packages
78 * Render version of configs''',
79 'State result': '''
80 * MySQL packages are upgraded''',
81 ])
82
83upgradeStageMap.put('Start MySQL service',
84 [
85 'Description': 'All MySQL services will be running on All TARGET_SERVERS nodes.',
86 'Status': 'NOT_LAUNCHED',
87 'Expected behaviors': '''
88 * MySQL service is running.
89 * OpenStack API are accessible from this point.
90 * No workload downtime''',
91 'Launched actions': '''
92 * Start MySQL service''',
93 'State result': 'MySQL service is running',
94 ])
95
96def env = "env"
97timeout(time: 12, unit: 'HOURS') {
98 node() {
99
100 stage('Setup virtualenv for Pepper') {
101 python.setupPepperVirtualenv(env, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
102 }
103
104 def upgradeTargets = salt.getMinionsSorted(env, TARGET_SERVERS)
105
106 if (upgradeTargets.isEmpty()) {
107 error("No servers for upgrade matched by ${TARGET_SERVERS}")
108 }
109
110 def targetSecMapping = [:]
111 def secNoList = []
112 def out
113 def stopTargets = upgradeTargets.reverse()
114 common.printStageMap(upgradeStageMap)
115
116 if (interactive){
117 input message: common.getColorizedString(
118 "Above you can find detailed info this pipeline will execute.\nThe info provides brief description of each stage, actions that will be performed and service/workload impact during each stage.\nPlease read it carefully.", "yellow")
119 }
120
121 for (target in upgradeTargets) {
122 salt.runSaltProcessStep(env, target, 'saltutil.refresh_pillar', [], null, true)
Roman Lubianyifb10a4d2022-02-11 12:37:46 +0200123 mysqlPillarVersion = salt.getPillar(env, target, "galera:version:mysql").get("return")[0].values()[0].toString().toLowerCase()
124 mysql56InstalledVersion = salt.getReturnValues(salt.runSaltProcessStep(env, target, 'pkg.version', 'mysql-wsrep-server-5.6', null, true)).toString().toLowerCase().take(3)
125 mysql57InstalledVersion = salt.getReturnValues(salt.runSaltProcessStep(env, target, 'pkg.version', 'mysql-wsrep-server-5.7', null, true)).toString().toLowerCase().take(3)
126
127 if (mysqlPillarVersion == '5.6' && mysql57InstalledVersion == '5.7') {
128 error("""Pre upgrade check failed. You are trying to downgrade MySQL package from 5.7 version to 5.6.
129 Check value for galera_mysql_version variable in your model.""")
130 }
131 if (mysqlPillarVersion == '5.7' && mysql56InstalledVersion == '5.6' && updateToMysql57 != true) {
132 error("""Pre upgrade check failed. You are trying to update MySQL package from version 5.6 to version 5.7 the wrong way.
133 If you want to update from 5.6 version to 5.7 set flag UPDATE_TO_MYSQL57 in the current job.
134 If you don't want to update from 5.6 version to 5.7 you need to change the value for galera_mysql_version to 5.6 in your model.""")
135 }
Roman Lubianyi1f5865f2022-02-15 11:55:50 +0200136 if (mysqlPillarVersion == '5.6' && updateToMysql57 == true) {
137 error("""Pre upgrade check failed. You are trying to update MySQL package from version 5.6 to version 5.7 the wrong way.
138 If you want to update from 5.6 version to 5.7 you need to set galera_mysql_version variable in your model to 5.7 value.
139 If you don't want to update from 5.6 version to 5.7 you need to unset flag UPDATE_TO_MYSQL57""")
140 }
Roman Lubianyifb10a4d2022-02-11 12:37:46 +0200141
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +0000142 salt.enforceState(env, target, ['linux.system.repo'])
143 common.stageWrapper(upgradeStageMap, "Pre upgrade", target, interactive) {
144 openstack.runOpenStackUpgradePhase(env, target, 'pre')
145 openstack.runOpenStackUpgradePhase(env, target, 'verify')
146 }
147 }
148
Roman Lubianyifb10a4d2022-02-11 12:37:46 +0200149 if (updateToMysql57 == true) {
150 shutdownCluster = true
151 }
152
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +0000153 if (shutdownCluster){
154 for (target in stopTargets) {
155 common.stageWrapper(upgradeStageMap, "Stop MySQL service", target, interactive) {
156 openstack.runOpenStackUpgradePhase(env, target, 'service_stopped')
157 }
158 }
159 }
160
Roman Lubianyi34603b32022-01-26 15:48:36 +0200161 def masterNode = salt.getMinionsSorted(env, galera.getGaleraLastShutdownNode(env))[0]
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +0000162 common.infoMsg("Master node is: ${masterNode}")
163
164 // Make sure we start upgrade always from master node
165 upgradeTargets.remove(masterNode)
166 upgradeTargets = [masterNode] + upgradeTargets
167 common.infoMsg("Upgrade targets are: ${upgradeTargets}")
168
169 for (target in upgradeTargets) {
170
171 common.stageWrapper(upgradeStageMap, "Stop MySQL service", target, interactive) {
172 openstack.runOpenStackUpgradePhase(env, target, 'service_stopped')
173 }
174
175 common.stageWrapper(upgradeStageMap, "Upgrade OS", target, interactive) {
176 if (OS_DIST_UPGRADE.toBoolean() == true){
177 upgrade_mode = 'dist-upgrade'
178 } else if (OS_UPGRADE.toBoolean() == true){
179 upgrade_mode = 'upgrade'
180 }
181 if (OS_DIST_UPGRADE.toBoolean() == true || OS_UPGRADE.toBoolean() == true) {
182 debian.osUpgradeNode(env, target, upgrade_mode, false)
183 }
184 }
185
186 common.stageWrapper(upgradeStageMap, "Upgrade MySQL server", target, interactive) {
Roman Lubianyifb10a4d2022-02-11 12:37:46 +0200187 if (updateToMysql57 == true) {
188 if (target == masterNode) {
189 openstack.runOpenStackUpgradePhase(env, target, 'update_master')
190 }
191 else {
192 openstack.runOpenStackUpgradePhase(env, target, 'update_slave')
193 }
194 }
195 else {
196 openstack.runOpenStackUpgradePhase(env, target, 'pkgs_latest')
197 openstack.runOpenStackUpgradePhase(env, target, 'render_config')
198 }
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +0000199 }
200
201 if (shutdownCluster && target == masterNode){
202 //Start first node.
203 common.stageWrapper(upgradeStageMap, "Start MySQL service", target, interactive) {
204 galera.startFirstNode(env, target)
205 }
206 }
207
208 common.stageWrapper(upgradeStageMap, "Start MySQL service", target, interactive) {
209 openstack.runOpenStackUpgradePhase(env, target, 'service_running')
210 openstack.runOpenStackUpgradePhase(env, target, 'verify')
211 }
212 }
213
214 // restart first node by applying state.
215
216 if (shutdownCluster) {
217 openstack.runOpenStackUpgradePhase(env, masterNode, 'render_config')
Roman Lubianyi10d70fd2022-01-26 16:00:01 +0200218 salt.cmdRun(env, masterNode, "systemctl restart mysql")
Oleksandr Bryndzii13bb1362019-06-14 14:46:39 +0000219 openstack.runOpenStackUpgradePhase(env, masterNode, 'verify')
220 }
221
222 for (target in upgradeTargets) {
223 ensureClusterState = galera.getWsrepParameters(env, target, 'wsrep_evs_state')
224 if (ensureClusterState['wsrep_evs_state'] == 'OPERATIONAL') {
225 common.infoMsg('Node is in OPERATIONAL state.')
226 } else {
227 throw new Exception("Node is NOT in OPERATIONAL state.")
228 }
229 }
230 }
231}