15
15
# limitations under the License.
16
16
17
17
18
+ import io
18
19
import xml .etree .ElementTree as ET
19
20
import os
20
21
import argparse
21
22
import json
22
23
24
+
25
+ ADDRESSES_TEMPLATE = """ <IpAddress wcm:action="add" wcm:keyValue="%(order)d">%(cidr)s</IpAddress>
26
+ """
27
+ INTERFACE_COMPONENT_TEMPLATE = """
28
+ <component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64"
29
+ publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
30
+ xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
31
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
32
+ <Interfaces>
33
+ <Interface wcm:action="add">
34
+ <Ipv4Settings>
35
+ <DhcpEnabled>false</DhcpEnabled>
36
+ </Ipv4Settings>
37
+ <Ipv6Settings>
38
+ <DhcpEnabled>false</DhcpEnabled>
39
+ </Ipv6Settings>
40
+ <Identifier>%(iface_id)s</Identifier>
41
+ <UnicastIpAddresses>
42
+ %(addresses)s </UnicastIpAddresses>
43
+ <Routes>%(routes)s
44
+ </Routes>
45
+ </Interface>
46
+ </Interfaces>
47
+ </component>
48
+ """
49
+ ROUTE_TEMPLATE = """
50
+ <Route wcm:action="add">
51
+ <Identifier>%(id)s</Identifier>
52
+ <Prefix>%(prefix)s</Prefix>
53
+ <NextHopAddress>%(gateway)s</NextHopAddress>
54
+ </Route>"""
55
+ DNS_TEMPLATE = """
56
+ <component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64"
57
+ publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
58
+ xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
59
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
60
+ <Interfaces>%(interfaces)s
61
+ </Interfaces>
62
+ </component>
63
+ """
64
+ DNS_INTERFACE_TEMPLATE = """
65
+ <Interface wcm:action="add">
66
+ <Identifier>%(iface_id)s</Identifier>
67
+ <DNSServerSearchOrder>%(dns_search_orders)s
68
+ </DNSServerSearchOrder>
69
+ </Interface>
70
+ """
71
+ DNS_SEARCH_ORDER_TEMPLATE = """
72
+ <IpAddress wcm:action="add" wcm:keyValue="%(key)s">%(server)s</IpAddress>"""
73
+ INTERFACE_ID = "Ethernet0"
74
+
75
+
23
76
def set_xmlstring (root , location , key , value ):
24
77
setting = root .find (location )
25
78
setting .find (key ).text = value
26
79
return setting
27
80
81
+
82
+ def ensure_interfaces (root , interfaces_content ):
83
+ setting = root .find ("*[@pass='specialize']" )
84
+ old_element = setting .find (".//*[@name='Microsoft-Windows-TCPIP']" )
85
+ modified = False
86
+ if old_element :
87
+ setting .remove (old_element )
88
+ modified = not interfaces_content
89
+
90
+ if interfaces_content :
91
+ interface_component_tree = ET .parse (io .StringIO (interfaces_content ))
92
+ new_element = interface_component_tree .getroot ()
93
+ setting .append (new_element )
94
+ modified = True
95
+
96
+ return setting , modified
97
+
98
+
99
+ def ensure_dns_settings (root , dns_content ):
100
+ setting = root .find ("*[@pass='specialize']" )
101
+ old_element = setting .find (".//*[@name='Microsoft-Windows-DNS-Client']" )
102
+ modified = False
103
+ if old_element :
104
+ setting .remove (old_element )
105
+ modified = not dns_content
106
+
107
+ if dns_content :
108
+ dns_component_tree = ET .parse (io .StringIO (dns_content ))
109
+ new_element = dns_component_tree .getroot ()
110
+ setting .append (new_element )
111
+ modified = True
112
+
113
+ return setting , modified
114
+
115
+
28
116
def main ():
29
117
parser = argparse .ArgumentParser (
30
118
description = "Updates select variables in autounattend.xml" )
@@ -55,7 +143,7 @@ def main():
55
143
with open (args .var_file , 'r' ) as f :
56
144
data = json .load (f )
57
145
58
- modified = 0
146
+ modified = False
59
147
os .chdir (args .build_dir )
60
148
unattend = ET .parse (args .unattend_file )
61
149
ET .register_namespace ('' , "urn:schemas-microsoft-com:unattend" )
@@ -65,18 +153,66 @@ def main():
65
153
root = unattend .getroot ()
66
154
67
155
if data .get ("unattend_timezone" ):
68
- modified = 1
156
+ modified = True
69
157
setting = set_xmlstring (root , ".//*[@pass='oobeSystem']/*[@name='Microsoft-Windows-Shell-Setup']" ,'{urn:schemas-microsoft-com:unattend}TimeZone' , data ["unattend_timezone" ])
70
158
print ("windows-ova-unattend: Setting Timezone to %s" % data ["unattend_timezone" ])
71
159
72
160
admin_password = data .get ("admin_password" )
73
161
if admin_password :
74
- modified = 1
162
+ modified = True
75
163
set_xmlstring (root , ".//*[@pass='oobeSystem']/*[@name='Microsoft-Windows-Shell-Setup']/{*}UserAccounts/{*}AdministratorPassword" ,'{urn:schemas-microsoft-com:unattend}Value' , admin_password )
76
164
set_xmlstring (root , ".//*[@pass='oobeSystem']/*[@name='Microsoft-Windows-Shell-Setup']/{*}AutoLogon/{*}Password" ,'{urn:schemas-microsoft-com:unattend}Value' , admin_password )
77
165
print ("windows-ova-unattend: Setting Administrator Password" )
78
166
79
- if modified == 1 :
167
+ addr_elements = []
168
+ ip_addr_cidr = data .get ("ipv4_address_cidr" )
169
+ gateway4 = data .get ("gateway4" )
170
+ if ip_addr_cidr :
171
+ modified = True
172
+ route_configs = []
173
+ if gateway4 :
174
+ route_configs .append (("0.0.0.0/0" , gateway4 ))
175
+
176
+ routes = []
177
+ for i in range (len (route_configs )):
178
+ route_config = route_configs [i ]
179
+ routes .append (ROUTE_TEMPLATE % {"id" : i + 1 , "prefix" : route_config [0 ], "gateway" : route_config [1 ]})
180
+ print ("windows-ova-unattend: Setting Gateway to %s" % route_config [1 ])
181
+
182
+ addrs = [ip_addr_cidr ]
183
+ for i in range (len (addrs )):
184
+ addr_elements .append (ADDRESSES_TEMPLATE % {"order" : i + 1 ,
185
+ "cidr" : addrs [i ]})
186
+ print ("windows-ova-unattend: Setting IP Address to %s" % ip_addr_cidr )
187
+
188
+ interfaces_content = None
189
+ if addr_elements :
190
+ interfaces_content = INTERFACE_COMPONENT_TEMPLATE % {"iface_id" : INTERFACE_ID ,
191
+ "addresses" : '' .join (addr_elements ),
192
+ "routes" : '' .join (routes )}
193
+
194
+ setting , xml_modified = ensure_interfaces (root , interfaces_content )
195
+ if xml_modified :
196
+ modified = True
197
+
198
+ dns_servers = data .get ("dns_servers" )
199
+ dns_servers_content = ''
200
+ if dns_servers :
201
+ dns_servers = dns_servers .split ()
202
+ search_order_content = []
203
+ for i in range (len (dns_servers )):
204
+ search_order_content .append (DNS_SEARCH_ORDER_TEMPLATE % {"key" : i + 1 ,
205
+ "server" : dns_servers [i ]})
206
+ dns_interface_content = [DNS_INTERFACE_TEMPLATE % {"iface_id" : INTERFACE_ID ,
207
+ "dns_search_orders" : '' .join (search_order_content )}]
208
+ dns_servers_content = DNS_TEMPLATE % {"interfaces" : '' .join (dns_interface_content )}
209
+ print ("windows-ova-unattend: Setting DNS Addresses to %s" % dns_servers )
210
+
211
+ setting , xml_modified = ensure_dns_settings (root , dns_servers_content )
212
+ if xml_modified :
213
+ modified = True
214
+
215
+ if modified :
80
216
print ("windows-ova-unattend: Updating %s ..." % args .unattend_file )
81
217
unattend .write (args .unattend_file )
82
218
else :
0 commit comments