stages.k8s.python.groovy 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. sharedLibsPath = "${env.WORKSPACE}/sharedLibs"
  2. backup_destination = '/var/jenkins_home/backups'
  3. backup_targetFile = 'dockerImage.tar'
  4. backup_num = 3
  5. // 获取镜像URL
  6. generateFullImageUri = {Map DOCKER, String base_branch, String BUILD_NUMBER ->
  7. return "${DOCKER.registry}/${DOCKER.image}:${base_branch}-${BUILD_NUMBER}"
  8. }
  9. // 获取镜像名
  10. generateImageName = {Map DOCKER, String base_branch, String BUILD_NUMBER ->
  11. return "${DOCKER.image}:${base_branch}-${BUILD_NUMBER}"
  12. }
  13. def cleanDockerImage(String dockerImgName) {
  14. sh "docker rmi ${dockerImgName}"
  15. }
  16. def backupDockerImage(String dockerImgName) {
  17. echo "-----> Backup artifact(docker image : ${dockerImgName}) ..."
  18. path = "${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}"
  19. sh """
  20. docker save ${dockerImgName} -o ${backup_targetFile}
  21. if [ -d ${path} ];
  22. then
  23. echo \"${path} already exists\"
  24. else
  25. mkdir -p ${path}
  26. fi
  27. mv ${backup_targetFile} ${path}
  28. """
  29. }
  30. def backupK8sConfigs(String[] files2backup) {
  31. path = "${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}/k8s"
  32. sh """if [ -d ${path} ];
  33. then
  34. echo \"${path} already exists!\"
  35. else
  36. mkdir -p ${path}
  37. fi
  38. """
  39. for(file in files2backup) {
  40. sh "cp -r ${file} ${path}"
  41. }
  42. }
  43. def generateDockerfile(Object SERVICE, String pathOfDockerfile='projdir') {
  44. def module = SERVICE.module == null ? '' : (SERVICE.module[-1] == '/' ? SERVICE.module : SERVICE.module + '/')
  45. echo "-----> Generating Dockerfile: ${pathOfDockerfile}/Dockerfile ..."
  46. sh """cat > ${pathOfDockerfile}/Dockerfile<<EOF
  47. FROM python:3.10-slim as final
  48. COPY ./requirements.txt /app
  49. COPY ./spider.py /app
  50. RUN pip install --upgrade pip
  51. RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
  52. RUN pip install --no-cache-dir -r requirements.txt
  53. EOF
  54. """
  55. return pathOfDockerfile
  56. }
  57. def buildDockerImage(Object SERVICE, Object DOCKER, String base_branch, projDir='projdir', String filter2Remove=null) {
  58. def imageUri = generateFullImageUri(DOCKER, base_branch, BUILD_NUMBER)
  59. echo "-----> Building docker image: ${imageUri} ..."
  60. dir(projDir) {
  61. docker.withRegistry("http://${DOCKER.registry}", "${DOCKER.push_credentialId}") {
  62. def imageName = generateImageName(DOCKER, base_branch, BUILD_NUMBER)
  63. def image = docker.build(imageName)
  64. image.push()
  65. sh "docker rmi ${imageName}"
  66. if(filter2Remove != null)
  67. sh "docker image prune --filter label=${filter2Remove} -f"
  68. }
  69. }
  70. return imageUri
  71. }
  72. def restoreDockerImage(Object DOCKER, String workspace, String base_branch, String rollbackBuildNumber) {
  73. dir(workspace) {
  74. imageUri = generateFullImageUri(DOCKER, base_branch, rollbackBuildNumber)
  75. // gunzip ${backup_targetFile}.tar.gz | docker load
  76. sh "docker load -i ${backup_targetFile}"
  77. // in case, docker image doesn't exist in remote registry
  78. docker.withRegistry("http://${DOCKER.registry}", "${DOCKER.push_credentialId}") {
  79. def image = docker.image(imageUri)
  80. image.push()
  81. }
  82. }
  83. return imageUri
  84. }
  85. def deployWithConfigmapEnvOnly(SERVICE, K3S, String base_branch, String[] args, configmapEnv="./configmap-env.ini", namespace='default') {
  86. print "loading ${sharedLibsPath}/k3sUtil.groovy..."
  87. def k3sUtils = load "${sharedLibsPath}/k3sUtil.groovy"
  88. def configmap_env_name = k3sUtils.applyConfigMapEnv(SERVICE, K3S, configmapEnv, namespace)
  89. def python_args = '['
  90. args.each{item -> python_args += "\"$item\","}
  91. python_args = python_args[0..-2] + ']'
  92. kvs = [:]
  93. kvs.put('<service_name>', SERVICE.name)
  94. kvs.put('<service_version>', SERVICE.version)
  95. kvs.put('<release>', base_branch)
  96. kvs.put('<COMMIT_SHA>', COMMIT_SHA)
  97. kvs.put('<imagePullSecret>', K3S.pull_secretId)
  98. kvs.put('<docker_image>', imageUri)
  99. kvs.put('<python_args>', python_args)
  100. if (SERVICE.health != null)
  101. kvs.put('<service_health>', SERVICE.health)
  102. kvs.put('<configmap_env_name>', configmap_env_name)
  103. k3sUtils.generateDeployment(kvs, 'deployment.yaml')
  104. k3sUtils.applyDeployment(K3S, 'deployment.yaml')
  105. k3sUtils.generateService(kvs, 'service.yaml')
  106. k3sUtils.applyService(K3S, 'service.yaml')
  107. }
  108. def deployWithConfigmapEnvOnly_rollback(SERVICE, K3S, String rollbackBuildNumber, String[] args, configmapEnv="./configmap-env.ini", namespace='default') {
  109. print "loading ${sharedLibsPath}/k3sUtil.groovy..."
  110. def k3sUtils = load "${sharedLibsPath}/k3sUtil.groovy"
  111. dir("${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}/k8s") {
  112. def configmap_env_name = k3sUtils.applyConfigMapEnv(SERVICE, K3S, configmapEnv, namespace)
  113. def java_args = '['
  114. args.each{item -> java_args += "\"$item\","}
  115. java_args = java_args[0..-2] + ']'
  116. kvs = [:]
  117. kvs.put('<service_name>', SERVICE.name)
  118. kvs.put('<service_version>', SERVICE.version)
  119. kvs.put('<release>', BASE_BRANCH)
  120. kvs.put('<COMMIT_SHA>', COMMIT_SHA)
  121. kvs.put('<imagePullSecret>', K3S.pull_secretId)
  122. kvs.put('<docker_image>', imageUri)
  123. kvs.put('<java_args>', java_args)
  124. if (SERVICE.health != null)
  125. kvs.put('<service_health>', SERVICE.health)
  126. kvs.put('<configmap_env_name>', configmap_env_name)
  127. k3sUtils.generateDeployment(kvs, 'deployment.yaml')
  128. k3sUtils.applyDeployment(K3S, 'deployment.yaml')
  129. k3sUtils.generateService(kvs, 'service.yaml')
  130. k3sUtils.applyService(K3S, 'service.yaml')
  131. }
  132. }
  133. def deployWithConfigmaps_rollback(SERVICE, K3S, String rollbackBuildNumber, String[] args, configmapEnv="./configmap-env.ini", configmapConf="./configmap") {
  134. print "loading ${sharedLibsPath}/k3sUtil.groovy..."
  135. def k3sUtils = load "${sharedLibsPath}/k3sUtil.groovy"
  136. dir("${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}/k8s") {
  137. def configmap_env_name = k3sUtils.applyConfigMapEnv(SERVICE, K3S, configmapEnv)
  138. def configmap_conf_name = k3sUtils.applyConfigMapConfig(SERVICE, K3S, configmapConf)
  139. def java_args = '['
  140. args.each{item -> java_args += "\"$item\","}
  141. java_args = java_args[0..-2] + ']'
  142. kvs = [:]
  143. kvs.put('<service_name>', SERVICE.name)
  144. kvs.put('<service_version>', SERVICE.version)
  145. kvs.put('<release>', BASE_BRANCH)
  146. kvs.put('<COMMIT_SHA>', COMMIT_SHA)
  147. kvs.put('<imagePullSecret>', K3S.pull_secretId)
  148. kvs.put('<docker_image>', imageUri)
  149. kvs.put('<java_args>', java_args)
  150. if (SERVICE.health != null)
  151. kvs.put('<service_health>', SERVICE.health)
  152. kvs.put('<configmap_env_name>', configmap_env_name)
  153. kvs.put('<configmap_conf_name>', configmap_conf_name)
  154. k3sUtils.generateDeployment(kvs, 'deployment.yaml')
  155. k3sUtils.applyDeployment(K3S, 'deployment.yaml')
  156. k3sUtils.generateService(kvs, 'service.yaml')
  157. k3sUtils.applyService(K3S, 'service.yaml')
  158. }
  159. }
  160. def deployWithConfigmaps(SERVICE, K3S, String base_branch, String[] args, configmapEnv="./configmap-env.ini", configmapConf="./configmap") {
  161. print "loading ${sharedLibsPath}/k3sUtil.groovy..."
  162. def k3sUtils = load "${sharedLibsPath}/k3sUtil.groovy"
  163. def configmap_env_name = k3sUtils.applyConfigMapEnv(SERVICE, K3S, configmapEnv)
  164. def configmap_conf_name = k3sUtils.applyConfigMapConfig(SERVICE, K3S, configmapConf)
  165. def java_args = '['
  166. args.each{item -> java_args += "\"$item\","}
  167. java_args = java_args[0..-2] + ']'
  168. kvs = [:]
  169. kvs.put('<service_name>', SERVICE.name)
  170. kvs.put('<service_version>', SERVICE.version)
  171. kvs.put('<release>', base_branch)
  172. kvs.put('<COMMIT_SHA>', COMMIT_SHA)
  173. kvs.put('<imagePullSecret>', K3S.pull_secretId)
  174. kvs.put('<docker_image>', imageUri)
  175. kvs.put('<java_args>', java_args)
  176. if (SERVICE.health != null)
  177. kvs.put('<service_health>', SERVICE.health)
  178. kvs.put('<configmap_env_name>', configmap_env_name)
  179. kvs.put('<configmap_conf_name>', configmap_conf_name)
  180. k3sUtils.generateDeployment(kvs, 'deployment.yaml')
  181. k3sUtils.applyDeployment(K3S, 'deployment.yaml')
  182. k3sUtils.generateService(kvs, 'service.yaml')
  183. k3sUtils.applyService(K3S, 'service.yaml')
  184. }
  185. def upgrade(Object CONFIG, String base_branch, String[] k8sBackupFiles, closures=[:]) {
  186. stage('Source code check out') {
  187. println "loading ${sharedLibsPath}/gitUtil.groovy..."
  188. def gitUtils = load "${sharedLibsPath}/gitUtil.groovy"
  189. COMMIT_SHA = closures.GITCLONE == null ? gitUtils.clone(CONFIG.git, base_branch) : closures.GITCLONE()
  190. if (closures.POST_GITCLONE != null)
  191. closures.POST_GITCLONE()
  192. }
  193. stage("Docker image build") {
  194. def projDir = 'projdir'
  195. if (closures.GENERATEDOCKERFILE != null)
  196. projDir = closures.GENERATEDOCKERFILE()
  197. else
  198. projDir = generateDockerfile(CONFIG.service) //default
  199. if (closures.BUILDIMAGE != null)
  200. imageUri = closures.BUILDIMAGE()
  201. else
  202. imageUri = buildDockerImage(CONFIG.service, CONFIG.docker, base_branch, projDir)
  203. // stage("Docker Image backup") {
  204. if (k8sBackupFiles != null && k8sBackupFiles.size() > 0) {
  205. backupDockerImage(imageUri)
  206. envFile = new File("${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}/env")
  207. envFile << "${COMMIT_SHA}\n"
  208. envFile << "${base_branch}\n"
  209. }
  210. // }
  211. cleanDockerImage(imageUri)
  212. }
  213. stage("Apply K8S ConfigMaps && Deployment") {
  214. // stage("K8s configs backup") {
  215. if (k8sBackupFiles != null && k8sBackupFiles.size() > 0)
  216. backupK8sConfigs(k8sBackupFiles)
  217. // }
  218. if (closures.K3SDEPLOY != null) {
  219. closures.K3SDEPLOY()
  220. return
  221. }
  222. }
  223. stage("Post Execution Script") {
  224. print "Clear older backup version"
  225. // 清理旧的备份
  226. dir("${backup_destination}/${JOB_NAME}") {
  227. sh """
  228. save_file=`ls -ltr | tail -${backup_num} | awk '{print \$NF}'`
  229. ls | grep -v "\$save_file" | xargs rm -rf
  230. """
  231. }
  232. }
  233. }
  234. def rollback(CONFIG, rollbackBuildNumber, closures=[:]) {
  235. // 1. restore specified version
  236. path = "${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}"
  237. if (fileExists(path)) {
  238. stage('Source code check out') {
  239. print("souce code check out. Skipped!")
  240. }
  241. envFile = new File("${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}/env")
  242. def lines = envFile.readLines()
  243. COMMIT_SHA = lines[0]
  244. BASE_BRANCH = lines[1]
  245. // 2. docker image build
  246. stage("Docker image build") {
  247. print("restore docker image from rollbackNo. #${rollbackBuildNumber}")
  248. imageUri = restoreDockerImage(CONFIG.docker, path, BASE_BRANCH, rollbackBuildNumber)
  249. cleanDockerImage(imageUri)
  250. }
  251. // 3. k8s configmap && deployment apply
  252. stage("Apply K8S ConfigMaps && Deployment") {
  253. if (closures.K3SDEPLOY != null)
  254. closures.K3SDEPLOY()
  255. }
  256. stage("Post Execution Script") {
  257. print "Clear rollback workspace"
  258. // 清理rollback工作目录
  259. dir("${backup_destination}/${JOB_NAME}") {
  260. sh "rm -rf *@tmp"
  261. }
  262. }
  263. }
  264. }
  265. return this