blob: 98a4338d0e501b8f4d2ca89f15898700527c9ac6 [file] [log] [blame]
Victor Ryzhenkinef34a022018-06-22 19:36:13 +04001/**
2 * Update kuberentes cluster
3 *
4 * Expected parameters:
5 * SALT_MASTER_CREDENTIALS Credentials to the Salt API.
6 * SALT_MASTER_URL Full Salt API address [https://10.10.10.1:8000].
7 * KUBERNETES_HYPERKUBE_IMAGE Target kubernetes version. May be null in case of reclass-system rollout
8 * KUBERNETES_PAUSE_IMAGE Kubernetes pause image should have same version as hyperkube. May be null in case of reclass-system rollout
9 * TARGET_UPDATES Comma separated list of nodes to update (Valid values are ctl,cmp)
10 * CTL_TARGET Salt targeted kubernetes CTL nodes (ex. I@kubernetes:master). Kubernetes control plane
11 * CMP_TARGET Salt targeted compute nodes (ex. cmp* and 'I@kubernetes:pool') Kubernetes computes
12 * PER_NODE Target nodes will be managed one by one (bool)
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +040013 * SIMPLE_UPGRADE Use previous version of upgrade without conron/drain abilities
14 * UPGRADE_DOCKER Upgrade docker component
Victor Ryzhenkinef34a022018-06-22 19:36:13 +040015 *
16**/
17def common = new com.mirantis.mk.Common()
18def salt = new com.mirantis.mk.Salt()
19def python = new com.mirantis.mk.Python()
20
21def updates = TARGET_UPDATES.tokenize(",").collect{it -> it.trim()}
22def pepperEnv = "pepperEnv"
23
24def overrideKubernetesImage(pepperEnv) {
25 def salt = new com.mirantis.mk.Salt()
26
27 def k8sSaltOverrides = """
28 kubernetes_hyperkube_image: ${KUBERNETES_HYPERKUBE_IMAGE}
29 kubernetes_pause_image: ${KUBERNETES_PAUSE_IMAGE}
30 """
31 stage("Override kubernetes images to target version") {
32 salt.setSaltOverrides(pepperEnv, k8sSaltOverrides)
33 }
34}
35
36def performKubernetesComputeUpdate(pepperEnv, target) {
37 def salt = new com.mirantis.mk.Salt()
38
39 stage("Execute Kubernetes compute update on ${target}") {
40 salt.enforceState(pepperEnv, target, 'kubernetes.pool')
41 salt.runSaltProcessStep(pepperEnv, target, 'service.restart', ['kubelet'])
42 }
43}
44
45def performKubernetesControlUpdate(pepperEnv, target) {
46 def salt = new com.mirantis.mk.Salt()
47
48 stage("Execute Kubernetes control plane update on ${target}") {
49 salt.enforceStateWithExclude(pepperEnv, target, "kubernetes", "kubernetes.master.setup")
50 // Restart kubelet
51 salt.runSaltProcessStep(pepperEnv, target, 'service.restart', ['kubelet'])
52 }
53}
54
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +040055def cordonNode(pepperEnv, target) {
56 def salt = new com.mirantis.mk.Salt()
57 def originalTarget = "I@kubernetes:master and not ${target}"
58
59 stage("Cordoning ${target} kubernetes node") {
60 def nodeShortName = target.tokenize(".")[0]
61 salt.cmdRun(pepperEnv, originalTarget, "kubectl cordon ${nodeShortName}", true, 1)
62 }
63}
64
65def uncordonNode(pepperEnv, target) {
66 def salt = new com.mirantis.mk.Salt()
67 def originalTarget = "I@kubernetes:master and not ${target}"
68
69 stage("Uncordoning ${target} kubernetes node") {
70 def nodeShortName = target.tokenize(".")[0]
71 salt.cmdRun(pepperEnv, originalTarget, "kubectl uncordon ${nodeShortName}", true, 1)
72 }
73}
74
75def drainNode(pepperEnv, target) {
76 def salt = new com.mirantis.mk.Salt()
77 def originalTarget = "I@kubernetes:master and not ${target}"
78
79 stage("Draining ${target} kubernetes node") {
80 def nodeShortName = target.tokenize(".")[0]
81 salt.cmdRun(pepperEnv, originalTarget, "kubectl drain --force --ignore-daemonsets --grace-period 100 --timeout 300s --delete-local-data ${nodeShortName}", true, 1)
82 }
83}
84
85def regenerateCerts(pepperEnv, target) {
86 def salt = new com.mirantis.mk.Salt()
87
88 stage("Regenerate certs for ${target}") {
89 salt.enforceState(pepperEnv, target, 'salt.minion.cert')
90 }
91}
92
Victor Ryzhenkinae909182018-10-02 17:49:18 +040093def updateAddons(pepperEnv, target) {
94 def salt = new com.mirantis.mk.Salt()
95
96 stage("Upgrading Addons at ${target}") {
Victor Ryzhenkin40625bc2018-10-04 16:15:27 +040097 salt.enforceState(pepperEnv, target, "kubernetes.master.kube-addons")
Victor Ryzhenkinfd9677f2018-10-16 16:14:40 +040098 }
99}
100
101def updateAddonManager(pepperEnv, target) {
102 def salt = new com.mirantis.mk.Salt()
103
104 stage("Upgrading AddonManager at ${target}") {
Victor Ryzhenkinae909182018-10-02 17:49:18 +0400105 salt.enforceState(pepperEnv, target, "kubernetes.master.setup")
106 }
107}
108
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +0400109def upgradeDocker(pepperEnv, target) {
110 def salt = new com.mirantis.mk.Salt()
111
112 stage("Upgrading docker at ${target}") {
113 salt.enforceState(pepperEnv, target, 'docker.host')
114 }
115}
Victor Ryzhenkinef34a022018-06-22 19:36:13 +0400116
117timeout(time: 12, unit: 'HOURS') {
118 node() {
119 try {
120
121 stage("Setup virtualenv for Pepper") {
122 python.setupPepperVirtualenv(pepperEnv, SALT_MASTER_URL, SALT_MASTER_CREDENTIALS)
123 }
124
125 if ((common.validInputParam('KUBERNETES_HYPERKUBE_IMAGE')) && (common.validInputParam('KUBERNETES_PAUSE_IMAGE'))) {
126 overrideKubernetesImage(pepperEnv)
127 }
128
129 /*
130 * Execute update
131 */
132 if (updates.contains("ctl")) {
133 def target = CTL_TARGET
134
135 if (PER_NODE.toBoolean()) {
136 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
137
138 for (t in targetHosts) {
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +0400139 if (SIMPLE_UPGRADE.toBoolean()) {
140 performKubernetesControlUpdate(pepperEnv, t)
141 } else {
142 cordonNode(pepperEnv, t)
143 drainNode(pepperEnv, t)
144 regenerateCerts(pepperEnv, t)
145 if (UPGRADE_DOCKER.toBoolean()) {
146 upgradeDocker(pepperEnv, t)
147 }
148 performKubernetesControlUpdate(pepperEnv, t)
Victor Ryzhenkinfd9677f2018-10-16 16:14:40 +0400149 updateAddonManager(pepperEnv, t)
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +0400150 uncordonNode(pepperEnv, t)
151 }
Victor Ryzhenkinef34a022018-06-22 19:36:13 +0400152 }
153 } else {
154 performKubernetesControlUpdate(pepperEnv, target)
155 }
Victor Ryzhenkinfd9677f2018-10-16 16:14:40 +0400156 if (!SIMPLE_UPGRADE.toBoolean()) {
157 // Addons upgrade should be performed after all nodes will upgraded
158 updateAddons(pepperEnv, target)
159 // Wait for 90 sec for addons reconciling
160 sleep(90)
161 }
Victor Ryzhenkinef34a022018-06-22 19:36:13 +0400162 }
163
164 if (updates.contains("cmp")) {
165 def target = CMP_TARGET
166
167 if (PER_NODE.toBoolean()) {
168 def targetHosts = salt.getMinionsSorted(pepperEnv, target)
169
170 for (t in targetHosts) {
Victor Ryzhenkin42e4b382018-09-11 17:57:56 +0400171 if (SIMPLE_UPGRADE.toBoolean()) {
172 performKubernetesComputeUpdate(pepperEnv, t)
173 } else {
174 cordonNode(pepperEnv, t)
175 drainNode(pepperEnv, t)
176 regenerateCerts(pepperEnv, t)
177 if (UPGRADE_DOCKER.toBoolean()) {
178 upgradeDocker(pepperEnv, t)
179 }
180 performKubernetesComputeUpdate(pepperEnv, t)
181 uncordonNode(pepperEnv, t)
182 }
Victor Ryzhenkinef34a022018-06-22 19:36:13 +0400183 }
184 } else {
185 performKubernetesComputeUpdate(pepperEnv, target)
186 }
187 }
188 } catch (Throwable e) {
189 // If there was an error or exception thrown, the build failed
190 currentBuild.result = "FAILURE"
191 currentBuild.description = currentBuild.description ? e.message + " " + currentBuild.description : e.message
192 throw e
193 }
194 }
195}