jjb: Add deb12-amd64 platform to linuxbuilds
[lttng-ci.git] / automation / ansible / scripts / update_jenkins_node.py
CommitLineData
c3c15dc7
KS
1#!/usr/bin/python3
2
3import argparse
4import configparser
5import sys
6import xml.etree.ElementTree
7
8import jenkins
9
10def get_argument_parser():
11 parser = argparse.ArgumentParser(
12 prog='update_jenkins_node.py',
13 description='Create, update, or delete Jenkins nodes'
14 )
15 parser.add_argument(
16 '-u', '--url', default=None,
17 help='Jenkins server URL including protocol'
18 )
19 parser.add_argument(
20 '--user', default=None,
21 help='Jenkins username'
22 )
23 parser.add_argument(
24 '--password', default=None,
25 help='Jenkins password'
26 )
27 parser.add_argument(
28 '-n', '--node', default=None, required=True,
29 help='The name of the node to manage in Jenkins'
30 )
31 parser.add_argument(
32 '-c', '--node-config', default=[], action='append',
33 help='An equals-separated set path=value[=attrib]. When attrib is not set, text is assumed'
34 )
35 parser.add_argument(
36 '-f', '--config-file', default=None, type=argparse.FileType('r'),
37 help='An INI config file as used by jenkins_jobs'
38 )
39 parser.add_argument(
40 '-s', '--state', default='online',
41 choices=['online', 'offline', 'absent'],
42 help='The state of the Jenkins node'
43 )
44 parser.add_argument(
45 '-m', '--message', default='',
46 help='A message to set for the offline reason of a node'
47 )
48 return parser
49
50
51def manage_node(url, user, password, node, state, offline_message='', config={}):
52 server = jenkins.Jenkins(url, username=user, password=password)
53 exists = server.node_exists(node)
54 node_info = {}
55 changed = False
56 if exists and state == 'absent':
57 server.delete_node(node)
58 changed = True
59 if not exists and state != 'absent':
60 server.create_node(node, numExecutors=1, remoteFS='/home/jenkins',
61 launcher=jenkins.LAUNCHER_SSH)
62 changed = True
63 if state != 'absent':
64 # Check configuration
65 updated = False
66 node_config = xml.etree.ElementTree.fromstring(server.get_node_config(node))
67 for key, value in config.items():
68 element = node_config.find(key)
69 new_element = None
70 current_key = key
71 while element is None:
72 head = key.rsplit('/', 1)[0] if '/' in current_key else None
73 tail = key.rsplit('/', 1)[1] if '/' in current_key else current_key
74 e = xml.etree.ElementTree.Element(tail)
75 if new_element is not None:
76 e.append(new_element)
77 new_element = None
78 if head is None:
79 node_config.append(e)
80 element = node_config.find(key)
81 else:
82 parent = node_config.find(head)
83 if parent:
84 parent.append(e)
85 element = node_config.find(key)
86 else:
87 new_element = e
88 current_key = head
89 continue
90
91 if value['attrib'] is None:
92 if element.text != value['value']:
93 updated = True
94 element.text = value['value']
95 else:
96 try:
97 if element.attrib[value['attrib']] != value['value']:
98 updated = True
99 element.attrib[value['attrib']] = value['value']
100 except KeyError:
101 element.attrib[value['attrib']] = value['value']
102 updated = True
103 if updated:
104 server.reconfig_node(
105 node,
106 xml.etree.ElementTree.tostring(
107 node_config,
108 xml_declaration=True,
109 encoding='unicode'
110 )
111 )
112 changed = True
113 # Online/offline
114 node_info = server.get_node_info(node)
115 if node_info['offline'] and state == 'online':
116 server.enable_node(node)
117 changed = True
118 if not node_info['offline'] and state == 'offline':
119 server.disable_node(node, offline_message)
120 changed = True
121 return changed
122
123
124if __name__ == '__main__':
125 parser = get_argument_parser()
126 args = parser.parse_args()
127 if args.config_file is not None:
128 config = configparser.ConfigParser()
129 config.read_file(args.config_file)
130 if 'jenkins' not in config.sections():
131 print("[jenkins] section not found")
132 sys.exit(1)
133 if args.url is None:
134 args.url = config.get('jenkins', 'url')
135 if args.user is None:
136 args.user = config['jenkins']['user']
137 if args.password is None:
138 args.password = config['jenkins']['password']
139 assert(args.user is not None)
140 assert(args.url is not None)
141 assert(args.password is not None)
142 node_config = {}
143 for entry in args.node_config:
144 key, value = entry.split('=', 1)
145 node_config[key] = {
146 'attrib': value.split('=', 1)[1] if '=' in value else None,
147 'value': value.split('=', 1)[0] if '=' in value else value,
148 }
149 print(node_config)
150 manage_node(
151 args.url, args.user, args.password, args.node, args.state,
152 args.message, node_config
153 )
This page took 0.048133 seconds and 4 git commands to generate.