-
Notifications
You must be signed in to change notification settings - Fork 77
/
esx-ks
executable file
·230 lines (209 loc) · 10.5 KB
/
esx-ks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
accepteula
<% if (installDisk === "firstdisk") { %>
clearpart --firstdisk --overwritevmfs
install --firstdisk --overwritevmfs
<% } else { %>
clearpart --drives=<%=installDisk%> --overwritevmfs
install --disk=<%=installDisk%> --overwritevmfs
<% } %>
rootpw <%=rootPlainPassword%>
# Search the networkDevices and set the first vmnic# (if defined) up.
# If no vmnic# device is specified in the networkDevices, then we fallback
# to setting vmnic0 up as dhcp
<% if( undefined !== networkDevices ) { %>
<% need_default = networkDevices.every(function(n) { %>
<% if( n.device.substring(0,5) === 'vmnic' ) { %>
<% if(typeof n.ipv4 !== 'undefined') { %>
<% ipopts = '--ip=' + n.ipv4.ipAddr + ' --gateway=' + n.ipv4.gateway + ' --netmask=' + n.ipv4.netmask %>
<% if (typeof n.ipv4.vlanId !== 'undefined' ) { %>
<% ipopts += ' --vlandid=' + n.ipv4.vlanId[0] %>
<% } %>
network --bootproto=static --device=<%=n.device%> <%=ipopts%>
<% } else { %>
network --bootproto=dhcp --device=<%=n.device%>
<% } %>
<% return false; %>
<% } %>
<% return true; %>
<% }); %>
<% if (need_default) { %>
network --bootproto=dhcp --device=vmnic0
<% } %>
<% } %>
reboot
%firstboot --interpreter=busybox
postLookup () {
echo "Attempting postLookup operation on $1" >> /vmfs/volumes/datastore1/firstboot.log
mac=`esxcli --debug --formatter=csv network ip interface list | grep $1 | awk -F, '{print $3}'`
if [ "<%=version%>" == "5.5" ]; then
mac=`esxcli --debug --formatter=csv network ip interface list | grep $1 | awk -F, '{print $2}'`
fi
BODY="{"
BODY=$BODY"\"macAddress\": \"$mac\","
BODY=$BODY"\"ipAddress\": \"$2\","
BODY=$BODY"\"node\": \"<%=task.nodeId%>\""
BODY=$BODY"}"
BODYLEN=$(echo -n ${BODY} | wc -c )
echo ${BODY} >> /vmfs/volumes/datastore1/firstboot.log
result=`echo -ne "POST /api/current/lookups HTTP/1.0\r\nHost: $2\r\nContent-Type: application/json\r\nContent-Length: ${BODYLEN}\r\n\r\n${BODY}" | nc -i 3 <%=server%> <%=port%> | grep -oE 'HTTP/1.1 [0-9]{3}' | awk '{print $2}'`
if [ "$result" -ge "400" ]; then
# Make an attempt to PATCH if we can find the node id. This is to handle the case where the
# ARP poller added the lookup entry when we tried to POST above causing a collision.
id=`wget http://<%=server%>:<%=port%>/api/current/lookups?q=$2 -qO - | grep -oE '\"id\":\"(.)*\"'`
if [ "$?" -eq "0" ]; then
id=`echo $id | awk -F: '{gsub(/"/,"",$2); print $2}'`
result=`echo -ne "PATCH /api/current/lookups/$id HTTP/1.0\r\nHost: $2\r\nContent-Type: application/json\r\nContent-Length: ${BODYLEN}\r\n\r\n${BODY}" | nc -i 3 <%=server%> <%=port%> | grep -oE 'HTTP/1.1 [0-9]{3}' | awk '{print $2}'`
echo "Patch result: $result to id: $id" >> /vmfs/volumes/datastore1/firstboot.log
fi
fi
wget http://<%=server%>:<%=port%>/api/current/lookups?q=$2 -qO - >> /vmfs/volumes/datastore1/firstboot.log
}
# enable VHV (Virtual Hardware Virtualization to run nested 64bit Guests + Hyper-V VM)
grep -i "vhv.enable" /etc/vmware/config || echo "vhv.enable = \"TRUE\"" >> /etc/vmware/config
vim-cmd hostsvc/enable_ssh
vim-cmd hostsvc/start_ssh
vim-cmd hostsvc/enable_esx_shell
vim-cmd hostsvc/start_esx_shell
#suppress shell warnings
esxcli system settings advanced set -o /UserVars/SuppressShellWarning -i 1
#Set the ESXi Shell Interactive idle time logout
esxcli system settings advanced set -o /UserVars/ESXiShellInteractiveTimeout -i 3600
# disable firewall
esxcli network firewall set --default-action false --enabled no
# set hostname and domain
esxcli system hostname set --domain <%=domain%> --host <%=hostname%>
#config root account
<% if (typeof rootSshKey !== 'undefined') { %>
echo <%=rootSshKey%> > /etc/ssh/keys-root/authorized_keys
<%} %>
#create users
<% users.forEach(function(user) { %>
/usr/lib/vmware/auth/bin/adduser -s /bin/sh -G root -h / -D <%=user.name%>
echo <%=user.plainPassword%> | passwd <%=user.name%> --stdin
<% if (typeof user.sshKey !== 'undefined') { %>
mkdir /etc/ssh/keys-<%=user.name%>
echo <%=user.sshKey%> > /etc/ssh/keys-<%=user.name%>/authorized_keys
<%} %>
<%}) %>
#setup ntp
cat > /etc/ntp.conf << __NTP_CONFIG__
restrict default kod nomodify notrap noquerynopeer
restrict 127.0.0.1 kkl,lkl
server 0.vmware.pool.ntp.org
server 1.vmware.pool.ntp.org
__NTP_CONFIG__
/sbin/chkconfig ntpd on
#enter maintenance mode
esxcli system maintenanceMode set -e true
#copy the first boot logs
cp /var/log/hostd.log "/vmfs/volumes/datastore1/firstboot-hostd.log"
cp /var/log/esxi_install.log "/vmfs/volumes/datastore1/firstboot-esxi_install.log"
<% if( undefined !== dnsServers ) { %>
esxcli network ip dns search add <%=domain%>
<% dnsServers.forEach(function(dns) { %>
esxcli network ip dns server add --server=<%= dns %>
<% }); %>
<% } %>
<% if ( typeof switchDevices !== 'undefined' ) { %>
<% switchDevices.forEach(function(n) { %>
esxcli network vswitch standard add -v "<%=n.switchName%>"
<% if( undefined !== n.uplinks ) { %>
<% n.uplinks.forEach(function(s) { %>
currsw=`esxcli --debug --formatter=csv network vswitch standard list | grep <%=s%> | awk -F, '{print $9}'`
if [ "$currsw" != "" ]; then
esxcli network vswitch standard uplink remove -v $currsw -u <%=s%>
fi
esxcli network vswitch standard uplink add -v <%=n.switchName%> -u <%=s%>
<% }); %>
<% } %>
<% }); %>
<% } %>
<% vmkid = 0 %>
<% if( undefined !== networkDevices ) { %>
<% networkDevices.forEach(function(n) { %>
<% if( undefined !== n.ipv4 ) { %>
<% if( undefined !== n.ipv4.vlanId ) { %>
<% n.ipv4.vlanId.forEach(function(vid) { %>
<% vmkname = 'vmk' + vmkid++ %>
esxcli network vswitch standard portgroup add -p <%=n.device%>.<%=vid%> -v "<%= typeof n.esxSwitchName!='undefined' ? n.esxSwitchName : 'vSwitch0' %>"
esxcli network ip interface remove -i <%=vmkname%>
esxcli network ip interface add -i <%=vmkname%> -p <%=n.device%>.<%=vid%>
esxcli network ip interface ipv4 set -i <%=vmkname%> -I <%=n.ipv4.ipAddr%> -N <%=n.ipv4.netmask%> -t static
esxcli network ip route ipv4 add -n default -g <%=n.ipv4.gateway%>
esxcli network vswitch standard portgroup set -p <%=n.device%>.<%=vid%> -v <%=vid %>
postLookup <%=vmkname%> <%=n.ipv4.ipAddr%>
<% }); %>
<% } else { %>
<% vmkname = 'vmk' + vmkid++ %>
esxcli network vswitch standard portgroup add -p <%=n.device%> -v <%= typeof n.esxSwitchName!='undefined' ? n.esxSwitchName : 'vSwitch0' %>
esxcli network ip interface remove -i <%=vmkname%>
esxcli network ip interface add -i <%=vmkname%> -p <%=n.device%>
esxcli network ip interface ipv4 set -i <%=vmkname%> -I <%=n.ipv4.ipAddr%> -N <%=n.ipv4.netmask%> -t static
esxcli network ip route ipv4 add -n default -g <%=n.ipv4.gateway%>
postLookup <%=vmkname%> <%=n.ipv4.ipAddr%>
<% } %>
<% } %>
<% if( undefined !== n.ipv6 ) { %>
<% if( undefined !== n.ipv6.vlanId ) { %>
<% n.ipv6.vlanId.forEach(function(vid) { %>
<% vmkname = 'vmk' + vmkid++ %>
esxcli network vswitch standard portgroup add -p <%=n.device%>.<%=vid%> -v <%= typeof n.esxSwitchName!='undefined' ? n.esxSwitchName : 'vSwitch0' %>
esxcli network ip interface remove -i <%=vmkname%>
esxcli network ip interface add -i <%=vmkname%> -p <%=n.device%>.<%=vid%>
esxcli network ip interface ipv6 address add -i <%=vmkname%> -I <%=n.ipv6.ipAddr%>
esxcli network vswitch standard portgroup set -p <%=n.device%>.<%=vid%> -v <%=vid %>
<% }); %>
<% } else { %>
<% vmkname = 'vmk' + vmkid++ %>
esxcli network vswitch standard portgroup add -p <%=n.device%> -v <%= typeof n.esxSwitchName!='undefined' ? n.esxSwitchName : 'vSwitch0' %>
esxcli network ip interface remove -i <%=vmkname%>
esxcli network ip interface add -i <%=vmkname%> -p <%=n.device%>
esxcli network ip interface ipv6 address add -i <%=vmkname%> -I <%=n.ipv6.ipAddr%>
<% } %>
<% } %>
<% if( (undefined === n.ipv6) && (undefined === n.ipv4) ) { %>
<% vmkname = 'vmk' + vmkid++ %>
esxcli network vswitch standard portgroup add -p <%=n.device%> -v <%= typeof n.esxSwitchName!='undefined' ? n.esxSwitchName : 'vSwitch0' %>
esxcli network ip interface remove -i <%=vmkname%>
esxcli network ip interface add -i <%=vmkname%> -p <%=n.device%>
esxcli network ip interface ipv4 set -i <%=vmkname%> -t dhcp
sleep 60
ip=`esxcli network ip interface ipv4 get | grep <%=vmkname%> | awk '{print $2}'`
postLookup <%=vmkname%> "$ip"
<% } %>
<% }); %>
<% } %>
<% if( typeof postInstallCommands !== 'undefined' ) { %>
<% postInstallCommands.forEach(function(n) { %>
<%=n%>
<% }); %>
<% } %>
# signify ORA the installation completed, the 60s sleep is to wait for the LRU to timeout
# the stale entries that it latched prior to the lookups loading above being set. Without
# the sleep, the completionUri hit below will not publish to the correct AMQP channel
sleep 60
# Download the service to callback to RackHD after OS installation/reboot completion
# %firstboot ends with a reboot, this script will run afterwards to signify completion
# of the installer and all reboot steps.
#
# The approved method for adding startup commands is to write to /etc/rc.local.d/local.sh,
# which is a pre-existing file with a sticky bit set by VisorFS. You can't just create new
# files and expect them to stick around, even if you set a sticky bit yourself.
# The /sbin/auto-backup.sh script will ensure the changes are persisted across reboots and
# MUST be executed after making any changes.
#
# See these links for more information:
# http://www.virtuallyghetto.com/2011/08/how-to-persist-configuration-changes-in.html
# http://blogs.vmware.com/vsphere/2011/09/how-often-does-esxi-write-to-the-boot-disk.html
# https://communities.vmware.com/message/1273849#1273849
#
# NOTE: this method only works for ESXi 5.1 or greater. For older versions, the changes
# must be written to /etc/rc.local instead.
#
# NOTE: this script will execute right away as a result of writing it to local.sh
# along with executing on every subsequent boot
wget http://<%=server%>:<%=port%>/api/common/templates/<%=rackhdCallbackScript%> -O /etc/rc.local.d/local.sh
#backup ESXi configuration to persist it
/sbin/auto-backup.sh
#reboot the system after host configuration
esxcli system shutdown reboot -d 10 -r "Rebooting after first boot host configuration"