-
Notifications
You must be signed in to change notification settings - Fork 0
/
heretic-host.ks
3915 lines (3456 loc) · 146 KB
/
heretic-host.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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Kickstart file for Heretic oVirt Project complete (plain-CentOS-based) host (called node anyway below)
# Note: minimum amount of RAM successfully tested for installation: 1536 MiB (test failed with 1024 MiB)
# Install from PXE with commandline (see below for comments):
# TODO: check each and every custom "hvp_" parameter below for overlap with default dracut/anaconda parameters and convert to using those instead
# nomodeset elevator=deadline inst.stage2=https://dangerous.ovirt.life/hvp-repos/el7/centos inst.ks=https://dangerous.ovirt.life/hvp-repos/el7/ks/heretic-host.ks hvp_nodeid=[0123]
# Note: DHCP is assumed to be available on one and only one network (the mgmt one, which will be autodetected, albeit with a noticeable delay) otherwise the ip=nicname:dhcp option must be added, where nicname is the name of the network interface to be used for installation (eg: ens32)
# Note: to force custom/fixed nic names add ifname=netN:AA:BB:CC:DD:EE:FF where netN is the desired nic name and AA:BB:CC:DD:EE:FF is the MAC address of the corresponding network interface (beware: not honored for bond slaves)
# Note: alternatively, to force legacy nic names (ethN), add biosdevname=0 net.ifnames=0
# Note: alternatively to install from DVD burn this kickstart into your CentOS image and append to default commandline:
# nomodeset elevator=deadline inst.ks=cdrom:/dev/cdrom:/ks/ks.cfg hvp_nodeid=[0123]
# Note: to access the running installation by SSH (beware of publishing the access informations specified with the sshpw directive below) add the option inst.sshd
# Note: to skip installing custom versions of Gluster-related/OVN packages add hvp_orthodox
# Note: to allow installing snapshot/nightly versions of oVirt packages add hvp_ovirt_nightly
# Note: to force use of VDO in nodes add hvp_use_vdo
# Note: to influence selection of the target disk for node OS installation add hvp_nodeosdisk=AAA where AAA is either the device name (sda, sdb ecc) or a qualifier like first, last, smallest, last-smallest
# Note: to force static nic name-to-MAC mapping add the option hvp_nicmacfix
# Note: to force custom node identity add hvp_nodeid=X where X is the node index
# Note: to force custom addressing add hvp_{mgmt,gluster,lan,internal}=x.x.x.x/yy where x.x.x.x may either be the node IP or the network address on the given network and yy is the prefix on the given network - other node addresses will count up and down from current node IP
# Note: to force custom test IPs add hvp_{mgmt,gluster,lan,internal}_test_ip=t.t.t.t where t.t.t.t is the test IP on the given network
# Note: to force custom node bonding mode add hvp_{mgmt,gluster,lan,internal}_bondmode=vvvv where vvvv is the bonding mode, either activepassive, roundrobin (only for gluster) or lacp
# Note: to force custom network MTU add hvp_{mgmt,gluster,lan,internal}_mtu=zzzz where zzzz is the MTU value
# Note: to force custom switch IP add hvp_switch=p.p.p.p where p.p.p.p is the switch IP
# Note: to force custom network domain naming add hvp_{mgmt,gluster,lan,internal}_domainname=mynet.name where mynet.name is the domain name
# Note: to force custom network bridge naming add hvp_{mgmt,gluster,lan,internal}_bridge=bridgename where bridgename is the bridge name
# Note: to force custom AD subdomain naming add hvp_ad_subdomainname=myprefix where myprefix is the subdomain name
# Note: to force custom AD DC IP add hvp_ad_dc=u.u.u.u where u.u.u.u is the AD DC IP on the AD network
# Note: to force custom nameserver IP (during installation) add hvp_nameserver=w.w.w.w where w.w.w.w is the nameserver IP
# Note: to force custom forwarders IPs add hvp_forwarders=forw0,forw1,forw2 where forwN are the forwarders IPs
# Note: to force custom gateway IP add hvp_gateway=n.n.n.n where n.n.n.n is the gateway IP
# Note: to force custom node count add hvp_nodecount=N where N is the number of nodes in the cluster
# Note: to force custom master node identity add hvp_masternodeid=Y where Y is the master node index
# Note: to force custom node naming add hvp_nodename=nodename0,nodename1,nodename2,nodename3 where nodenameN are the unqualified (ie without domain name part) hostnames
# Note: to force custom installer naming add hvp_installername=myinstallername where myinstallername is the unqualified (ie without domain name part) hostname of the installer management interface
# Note: to force custom switch naming add hvp_switchname=myswitchname where myswitchname is the unqualified (ie without domain name part) hostname of the switch management interface
# Note: to force custom engine naming add hvp_enginename=myenginename where myenginename is the unqualified (ie without domain name part) hostname of the Engine
# Note: to force custom metrics server naming add hvp_metricsname=mymetricsname where mymetricsname is the unqualified (ie without domain name part) hostname of the metrics server
# Note: to force custom storage naming add hvp_storagename=mystoragename where mystoragename is the unqualified (ie without domain name part) hostname of the storage
# Note: to force custom Gluster volume naming add hvp_{engine,vmstore,iso,ctdb,unixshare,winshare,blockshare,backup}_volumename=myvolumename where myvolumename is the volume name
# Note: to force custom node BMC IP offsets add hvp_bmcs_offset=M where M is the offset
# Note: to force custom node IP offsets add hvp_nodes_offset=L where L is the offset
# Note: to force custom engine IP add hvp_engine=m.m.m.m where m.m.m.m is the engine IP on the mgmt network
# Note: to force custom metrics server IP add hvp_metrics=n.n.n.n where n.n.n.n is the metrics server IP on the mgmt network
# Note: to force custom storage IPs add hvp_storage_offset=o where o is the storage IPs base offset on mgmt/lan/internal networks
# Note: to force custom root password add hvp_rootpwd=mysecret where mysecret is the root user password
# Note: to force custom admin username add hvp_adminname=myadmin where myadmin is the admin username
# Note: to force custom admin password add hvp_adminpwd=myothersecret where myothersecret is the admin user password
# Note: to force custom email address for notification receiver add hvp_receiver_email=name@domain where name@domain is the email address
# Note: to force custom keyboard layout add hvp_kblayout=cc where cc is the country code
# Note: to force custom local timezone add hvp_timezone=VV where VV is the timezone specification
# Note: to force custom oVirt version add hvp_ovirt_version=OO where OO is the version (either 4.1, 4.2 or master)
# Note: to force custom Yum retries on failures add hvp_yum_retries=RR where RR is the number of retries
# Note: to force custom Yum sleep time on failures add hvp_yum_sleep_time=SS where SS is the number of seconds between retries after each failure
# Note: to force custom repo base URL for repo reponame add hvp_reponame_baseurl=HHHHH where HHHHH is the base URL (including variables like $releasever and $basearch)
# Note: to force custom repo GPG key URL for repo reponame add hvp_reponame_gpgkey=GGGGG where GGGGG is the GPG key URL
# Note: the default behaviour involves installing custom versions of Gluster-related/OVN packages
# Note: the default behaviour involves ignoring snapshot/nightly versions of oVirt packages
# Note: the default behaviour involves ignoring use of VDO on nodes
# Note: the default node OS disk is the first of the smallests
# Note: the default behaviour does not register fixed nic name-to-MAC mapping
# Note: the default node id is assumed to be 0
# Note: the default addressing on connected networks is assumed to be 172.20.{10,11,12,13}.0/24 on {mgmt,gluster,lan,internal} respectively with nodes addresses starting from 10 (adding node id)
# Note: the default node bonding mode is assumed to be activepassive on {mgmt,lan,gluster,internal}
# Note: the default MTU is assumed to be 1500 on {mgmt,lan,gluster,internal}
# Note: the default test IPs are assumed to be the first IPs available (network address + 1) on each connected network
# Note: the default switch IP is assumed to be the 200th IP available (network address + 200) on the mgmt network
# Note: the default domain names are assumed to be {mgmt,gluster,lan,internal}.private
# Note: the default bridge names are assumed to be {ovirtmgmt,,lan,internal}
# Note: the default AD subdomain name is assumed to be ad
# Note: the default AD DC IP on the AD network is assumed to be the AD network address plus 220
# Note: the default nameserver IP is assumed to be 8.8.8.8 during installation (afterwards it will be switched to 127.0.0.1 unconditionally)
# Note: the default forwarder IP is assumed to be 8.8.8.8
# Note: the default gateway IP is assumed to be equal to the test IP on the mgmt network
# Note: the default node count is 3
# Note: the default master node id is assumed to be 0
# Note: the default node naming uses "My Little Pony" character names {pinkiepie,applejack,rarity,fluttershy} for node ids {0,1,2,3} and nodeN for further ones
# Note: the default installer naming uses the "My Little Pony" character name twilight for the installer
# Note: the default switch naming uses the "My Little Pony" character name scootaloo for the switch
# Note: the default engine naming uses the "My Little Pony" character name celestia for the Engine
# Note: the default metrics server naming uses the "My Little Pony" character name luna for the metrics server
# Note: the default storage naming uses the "My Little Pony" character name discord for the storage service
# Note: the default Gluster volume naming uses the names {engine,vmstore,iso,ctdb,unixshare,winshare,blockshare,backup}
# Note: the default nodes BMC IP offset is 100
# Note: the default nodes IP offset is 10
# Note: the default engine IP on the mgmt network is assumed to be the mgmt network address plus 5
# Note: the default metrics server IP on the mgmt network is assumed to be the mgmt network address plus 6
# Note: the default storage IPs base offset on mgmt/lan/internal networks is assumed to be the network address plus 30
# Note: the default root user password is HVP_dem0
# Note: the default admin username is hvpadmin
# Note: the default admin user password is hvpdemo
# Note: the default notification email address for receiver is monitoring@localhost
# Note: the default keyboard layout is us
# Note: the default local timezone is UTC
# Note: the default oVirt version is 4.1
# Note: the default number of retries after a Yum failure is 10
# Note: the default sleep time between retries after a Yum failure is 10 seconds
# Note: the default repo base URL for each required repo is that which is included into the default .repo file from the latest release package for each repo
# Note: the default repo GPG key URL for each required repo is that which is included into the default .repo file from the latest release package for each repo
# Note: to work around a known kernel commandline length limitation, all hvp_* parameters above can be omitted and proper default values (overriding the hardcoded ones) can be placed in Bash-syntax variables-definition files placed alongside the kickstart file - the name of the files retrieved and sourced (in the exact order) is: hvp_parameters.sh hvp_parameters_heretic_ngn.sh hvp_parameters_heretic_host.sh hvp_parameters_hh:hh:hh:hh:hh:hh.sh (where hh:hh:hh:hh:hh:hh is the MAC address of the nic used to retrieve the kickstart file)
# Perform an installation (as opposed to an "upgrade")
install
# Avoid asking interactive confirmation for unsupported hardware
unsupported_hardware
# Uncomment the line below to receive debug messages on a syslog server
# logging --host=192.168.229.1 --level=info
# Use text mode (as opposed to "cmdline", "graphical" or "vnc")
text
# Uncomment the line below to automatically reboot at the end of installation
# (must be sure that system does not try to loop-install again and again)
reboot
# Installation source configuration dynamically generated in pre section below
%include /tmp/full-installsource
# System localization configuration dynamically generated in pre section below
%include /tmp/full-localization
# Network interface configuration dynamically generated in pre section below
%include /tmp/full-network
# Control "First Boot" interactive tool execution
# TODO: the following seems to be started anyway even if disabled manually in post section below - see https://bugzilla.redhat.com/show_bug.cgi?id=1213114
firstboot --disable
# EULA is implicitly accepted
eula --agreed
# Do not configure X Windows (as opposed to an "xconfig" line)
skipx
# Fail safe X Windows configuration
#xconfig --defaultdesktop=GNOME --startxonboot
# Control automatically enabled/disabled services for OS-supplied packages
services --disabled="mdmonitor,multipathd,lm_sensors,iscsid,iscsiuio,fcoe,fcoe-target,lldpad,iptables,ip6tables,ksm,ksmtuned,tuned,libvirtd,libvirt-guests,qpidd,tog-pegasus,cups,portreserve,postfix,nfs,nfs-lock,rpcbind,rpc-idmapd,rpc-gssd,rpc-svcgssd,pcscd,avahi-daemon,network,bluetooth,gpm,vsftpd,vncserver,slapd,dnsmasq,ipmi,ipmievd,nscd,psacct,rdisc,rwhod,saslauthd,smb,nmb,snmptrapd,svnserve,winbind,oddjobd,autofs,wpa_supplicant,kdump,iprdump,iprinit,iprupdate,snmpd" --enabled="firewalld,NetworkManager,NetworkManager-wait-online,ntpdate,chronyd,named,dhcpd"
# Users configuration dynamically generated in pre section below
%include /tmp/full-users
# Firewall (firewalld) enabled
# Note: further configuration performed in post section below
firewall --enabled --ssh
# Configure authentication mode
authconfig --enableshadow --passalgo=sha512
# Leave SELinux on (default will be "targeted" mode)
selinux --enforcing
# Disable kdump
%addon com_redhat_kdump --disable
%end
# Disk configuration dynamically generated in pre section below
%include /tmp/full-disk
# Packages list - package groups are preceded by an "@" sign - excluded packages by an "-" sign
# Note: virtualization related packages will be installed by oVirt below
%packages
@system-admin-tools
@console-internet
@core
@base
@large-systems
@performance
-gnome-boxes
-perl-homedir
policycoreutils-python
policycoreutils-newrole
mcstrans
stunnel
-xinetd
-ntp
# Note: the following is not installed by default and not advisable in a IPMI-controlled cluster node - explicitly excluded here in case some dependency brings it in again
-acpid
# Note: the following seems to be missing by default and we explicitly include it to allow efficient updates even in absence of our fast local mirror
deltarpm
rdate
symlinks
dos2unix
unix2dos
screen
minicom
telnet
tree
audit
iptraf
iptstate
bridge-utils
ebtables
arptables_jf
device-mapper-multipath
lm_sensors
OpenIPMI
ipmitool
hdparm
sdparm
lsscsi
xfsprogs
xfsdump
rsyslog-relp
rsyslog-gnutls
rsyslog-gssapi
openldap-clients
cyrus-sasl-gssapi
nss-tools
rsync
wget
patch
expect
setserial
ntpdate
redhat-lsb-core
ncompress
libnl
-zsh
-nmap
-xdelta
-samba-client
-bluez-hcidump
-bluez-gnome
-slrn
-fetchmail
-mutt
-cadaver
-coolkey
-finger
-autofs
-conman
-pcmciautils
-ypbind
-ccid
-bluez-utils
-mod_python
-mod_perl
%end
# Pre-installation script (run with bash from stage2.img immediately after parsing this kickstart file)
%pre
( # Run the entire pre section as a subshell for logging.
# Discover exact pre-stage environment
echo "PRE env" >> /tmp/pre.out
env >> /tmp/pre.out
echo "PRE devs" >> /tmp/pre.out
ls -l /dev/* >> /tmp/pre.out
echo "PRE block" >> /tmp/pre.out
ls -l /sys/block/* >> /tmp/pre.out
echo "PRE mounts" >> /tmp/pre.out
df -h >> /tmp/pre.out
echo "PRE progs" >> /tmp/pre.out
for pathdir in $(echo "${PATH}" | sed -e 's/:/ /'); do
if [ -d "${pathdir}" ]; then
ls "${pathdir}"/* >> /tmp/pre.out
fi
done
# A simple regex matching IP addresses
IPregex='[0-9]*[.][0-9]*[.][0-9]*[.][0-9]*'
# A general IP add/subtract function to allow classless subnets +/- offsets
# Note: derived from https://stackoverflow.com/questions/33056385/increment-ip-address-in-a-shell-script
# TODO: add support for IPv6
ipmat() {
local given_ip=$1
local given_diff=$2
local given_op=$3
# TODO: perform better checking on parameters
if [ -z "${given_ip}" -o -z "${given_diff}" -o -z "${given_op}" ]; then
echo ""
return 255
fi
local given_ip_hex=$(printf '%.2X%.2X%.2X%.2X' $(echo "${given_ip}" | sed -e 's/\./ /g'))
local given_diff_hex=$(printf '%.8X' "${given_diff}")
local result_ip_hex=$(printf '%.8X' $(echo $(( 0x${given_ip_hex} ${given_op} 0x${given_diff_hex} ))))
local result_ip=$(printf '%d.%d.%d.%d' $(echo "${result_ip_hex}" | sed -r 's/(..)/0x\1 /g'))
echo "${result_ip}"
return 0
}
# Define all cluster default network data
# Note: engine-related data will only be used for automatic DNS zones configuration
unset nicmacfix
unset orthodox_mode
unset ovirt_nightly_mode
unset use_vdo
unset node_count
unset network
unset netmask
unset network_base
unset bondopts
unset mtu
unset domain_name
unset ad_subdomain_prefix
unset ad_dc_ip
unset ad_dc_ip_offset
unset reverse_domain_name
unset bridge_name
unset node_name
unset bmc_ip_offset
unset node_ip_offset
unset test_ip
unset test_ip_offset
unset switch_ip
unset switch_ip_offset
unset installer_name
unset switch_name
unset engine_name
unset metrics_name
unset storage_name
unset gluster_vol_name
unset engine_ip
unset engine_ip_offset
unset metrics_ip
unset metrics_ip_offset
unset storage_ip_offset
unset master_index
unset my_index
unset my_name
unset my_nameserver
unset my_forwarders
unset my_gateway
unset root_password
unset admin_username
unset admin_password
unset notification_receiver
unset keyboard_layout
unset local_timezone
unset ovirt_version
unset hvp_repo_baseurl
unset hvp_repo_gpgkey
# Hardcoded defaults
nicmacfix="false"
orthodox_mode="false"
ovirt_nightly_mode="false"
use_vdo="false"
default_nodeosdisk="smallest"
default_node_count="3"
default_node_index="0"
declare -A node_name
node_name[0]="pinkiepie"
node_name[1]="applejack"
node_name[2]="rarity"
node_name[3]="fluttershy"
installer_name="twilight"
switch_name="scootaloo"
engine_name="celestia"
metrics_name="luna"
storage_name="discord"
declare -A hvp_repo_baseurl
declare -A hvp_repo_gpgkey
declare -A gluster_vol_name
gluster_vol_name['engine']="engine"
gluster_vol_name['vmstore']="vmstore"
gluster_vol_name['iso']="iso"
gluster_vol_name['ctdb']="ctdb"
gluster_vol_name['unixshare']="unixshare"
gluster_vol_name['winshare']="winshare"
gluster_vol_name['blockshare']="blockshare"
gluster_vol_name['backup']="backup"
# Note: IP offsets below get used to automatically derive IP addresses
# Note: no need to allow offset overriding from commandline if the IP address itself can be specified
# Note: the following can be overridden from commandline
test_ip_offset="1"
# Note: the following can be overridden from commandline
switch_ip_offset="200"
# TODO: verify whether the final addresses (network+offset+index) lie inside the network boundaries
# Note: the following can be overridden from commandline
bmc_ip_offset="100"
# TODO: verify whether the final addresses (network+offset+index) lie inside the network boundaries
# Note: the following can be overridden from commandline
node_ip_offset="10"
# TODO: verify whether the address (network+offset) lies inside the network boundaries
engine_ip_offset="5"
# TODO: verify whether the address (network+offset) lies inside the network boundaries
metrics_ip_offset="6"
# TODO: verify whether the final addresses (network+offset+index) lie inside the network boundaries
# TODO: verify whether the final addresses (network+offset+index) overlap with base node addresses
# Note: the following can be overridden from commandline
storage_ip_offset="30"
# Note: the following can be overridden from commandline
master_index="0"
declare -A network netmask network_base bondopts mtu
network['mgmt']="172.20.10.0"
netmask['mgmt']="255.255.255.0"
network_base['mgmt']="172.20.10"
bondopts['mgmt']="mode=active-backup;miimon=100"
mtu['mgmt']="1500"
network['gluster']="172.20.11.0"
netmask['gluster']="255.255.255.0"
network_base['gluster']="172.20.11"
bondopts['gluster']="mode=active-backup;miimon=100"
mtu['gluster']="1500"
network['lan']="172.20.12.0"
netmask['lan']="255.255.255.0"
network_base['lan']="172.20.12"
bondopts['lan']="mode=active-backup;miimon=100"
mtu['lan']="1500"
network['internal']="172.20.13.0"
netmask['internal']="255.255.255.0"
network_base['internal']="172.20.13"
bondopts['internal']="mode=active-backup;miimon=100"
mtu['internal']="1500"
declare -A domain_name
domain_name['mgmt']="mgmt.private"
domain_name['gluster']="gluster.private"
domain_name['lan']="lan.private"
domain_name['internal']="internal.private"
declare -A reverse_domain_name
reverse_domain_name['mgmt']="10.20.172.in-addr.arpa"
reverse_domain_name['gluster']="11.20.172.in-addr.arpa"
reverse_domain_name['lan']="12.20.172.in-addr.arpa"
reverse_domain_name['internal']="13.20.172.in-addr.arpa"
declare -A bridge_name
bridge_name['mgmt']="ovirtmgmt"
bridge_name['lan']="lan"
bridge_name['internal']="internal"
ad_subdomain_prefix="ad"
ad_dc_ip_offset="220"
declare -A test_ip
# Note: default values for test_ip derived below - defined here to allow loading as configuration parameters
my_nameserver="8.8.8.8"
my_forwarders="8.8.8.8"
root_password="HVP_dem0"
admin_username="hvpadmin"
admin_password="hvpdemo"
keyboard_layout="us"
local_timezone="UTC"
notification_receiver="monitoring@localhost"
ovirt_version="4.1"
# Detect any configuration fragments and load them into the pre environment
# Note: incomplete (no device or filename), BIOS based devices, UUID, file and DHCP methods are unsupported
ks_custom_frags="hvp_parameters.sh hvp_parameters_heretic_ngn.sh hvp_parameters_heretic_host.sh"
mkdir /tmp/kscfg-pre
mkdir /tmp/kscfg-pre/mnt
ks_source="$(cat /proc/cmdline | sed -n -e 's/^.*\s*inst\.ks=\(\S*\)\s*.*$/\1/p')"
if [ -z "${ks_source}" ]; then
# Note: if we are here and no Kickstart has been explicitly specified, then it must have been found by OEMDRV method (needs CentOS >= 7.2)
ks_source='hd:LABEL=OEMDRV'
fi
if [ -n "${ks_source}" ]; then
ks_dev=""
if echo "${ks_source}" | grep -q '^floppy' ; then
# Note: hardcoded device name for floppy disk
ks_dev="/dev/fd0"
# Note: filesystem type on floppy disk autodetected
ks_fstype="*"
ks_fsopt="ro"
ks_path="$(echo ${ks_source} | awk -F: '{print $2}')"
if [ -z "${ks_path}" ]; then
ks_path="/ks.cfg"
fi
ks_dir="$(echo ${ks_path} | sed -e 's%/[^/]*$%%')"
elif echo "${ks_source}" | grep -q '^cdrom' ; then
# Note: cdrom gets accessed as real device name which must be detected - assuming it is the first removable device
# Note: hardcoded possible device names for CD/DVD - should cover all reasonable cases
# Note: on RHEL>=6 even IDE/ATAPI devices have SCSI device names
for dev in /dev/sd[a-z] /dev/sr[0-9]; do
if [ -b "${dev}" ]; then
is_removable="$(cat /sys/block/$(basename ${dev})/removable 2>/dev/null)"
if [ "${is_removable}" = "1" ]; then
ks_dev="${dev}"
ks_fstype="iso9660"
ks_fsopt="ro"
ks_path="$(echo ${ks_source} | awk -F: '{print $2}')"
if [ -z "${ks_path}" ]; then
ks_path="/ks.cfg"
ks_dir="/"
else
ks_dir="$(echo ${ks_path} | sed -e 's%/[^/]*$%%')"
fi
break
fi
fi
done
elif echo "${ks_source}" | grep -q '^hd:' ; then
# Note: blindly extracting device name from Kickstart commandline
ks_spec="$(echo ${ks_source} | awk -F: '{print $2}')"
ks_dev="/dev/${ks_spec}"
# Detect LABEL-based device selection
if echo "${ks_spec}" | grep -q '^LABEL=' ; then
ks_label="$(echo ${ks_spec} | awk -F= '{print $2}')"
if [ -z "${ks_label}" ]; then
echo "Invalid definition of Kickstart labeled device" 1>&2
ks_dev=""
else
ks_dev=/dev/$(lsblk -r -n -o name,label | awk "/\\<$(echo ${ks_label} | sed -e 's%\([./*\\]\)%\\\1%g')\\>/ {print \$1}" | head -1)
fi
fi
# Note: filesystem type on local drive autodetected
ks_fstype="*"
ks_fsopt="ro"
ks_path="$(echo ${ks_source} | awk -F: '{print $3}')"
if [ -z "${ks_path}" ]; then
ks_path="/ks.cfg"
ks_dir="/"
else
ks_dir="$(echo ${ks_path} | sed -e 's%/[^/]*$%%')"
fi
elif echo "${ks_source}" | grep -q '^nfs:' ; then
# Note: blindly extracting NFS server from Kickstart commandline
ks_host="$(echo ${ks_source} | awk -F: '{print $2}')"
ks_fstype="nfs"
# TODO: support NFS options
ks_fsopt="ro,nolock"
ks_path="$(echo ${ks_source} | awk -F: '{print $3}')"
if [ -z "${ks_path}" ]; then
echo "Unable to determine Kickstart NFS source path" 1>&2
ks_dev=""
else
ks_dev="${ks_host}:$(echo ${ks_path} | sed -e 's%/[^/]*$%%')}"
ks_dir="/"
fi
elif echo "${ks_source}" | egrep -q '^(http|https|ftp):' ; then
# Note: blindly extracting URL from Kickstart commandline
ks_host="$(echo ${ks_source} | sed -e 's%^.*//%%' -e 's%/.*$%%')"
ks_dev="$(echo ${ks_source} | sed -e 's%/[^/]*$%%')"
ks_fstype="url"
else
echo "Unsupported Kickstart source detected" 1>&2
fi
if [ -z "${ks_dev}" ]; then
echo "Unable to extract Kickstart source - skipping configuration fragments retrieval" 1>&2
else
# Note: for network-based kickstart retrieval methods we extract the relevant nic MAC address to get the machine-specific fragment
if [ "${ks_fstype}" = "url" -o "${ks_fstype}" = "nfs" ]; then
# Note: we detect the nic device name as the one detaining the route towards the host holding the kickstart script
# Note: regarding the kickstart host: we assume that if it is not already been given as an IP address then it is a DNS fqdn
if ! echo "${ks_host}" | grep -q "${IPregex}" ; then
ks_host_ip=$(nslookup "${ks_host}" | tail -n +3 | awk '/^Address/ {print $2}' | head -1)
else
ks_host_ip="${ks_host}"
fi
ks_nic=$(ip route get "${ks_host_ip}" | sed -n -e 's/^.*\s\+dev\s\+\(\S\+\)\s\+.*$/\1/p')
if [ -f "/sys/class/net/${ks_nic}/address" ]; then
ks_custom_frags="${ks_custom_frags} hvp_parameters_$(cat /sys/class/net/${ks_nic}/address).sh"
fi
fi
if [ "${ks_fstype}" = "url" ]; then
for custom_frag in ${ks_custom_frags} ; do
echo "Attempting network retrieval of ${ks_dev}/${custom_frag}" 1>&2
wget -P /tmp/kscfg-pre "${ks_dev}/${custom_frag}"
done
else
# Note: filesystem type autodetected
mount -o ${ks_fsopt} ${ks_dev} /tmp/kscfg-pre/mnt
for custom_frag in ${ks_custom_frags} ; do
echo "Attempting filesystem retrieval of ${custom_frag}" 1>&2
if [ -f "/tmp/kscfg-pre/mnt${ks_dir}/${custom_frag}" ]; then
cp "/tmp/kscfg-pre/mnt${ks_dir}/${custom_frag}" /tmp/kscfg-pre
fi
done
umount /tmp/kscfg-pre/mnt
fi
fi
fi
# Load any configuration fragment found, in the proper order
# Note: configuration-fragment defaults will override hardcoded defaults
# Note: commandline parameters will override configuration-fragment and hardcoded defaults
# Note: configuration fragments get executed with full privileges and no further controls beside a bare syntax check: obvious security implications must be taken care of (use HTTPS for network-retrieved kickstart and fragments)
pushd /tmp/kscfg-pre
for custom_frag in ${ks_custom_frags} ; do
if [ -f "${custom_frag}" ]; then
# Perform a configuration fragment sanity check before loading
bash -n "${custom_frag}" > /dev/null 2>&1
res=$?
if [ ${res} -ne 0 ]; then
# Report invalid configuration fragment and skip it
logger -s -p "local7.err" -t "kickstart-pre" "Skipping invalid remote configuration fragment ${custom_frag}"
continue
fi
source "./${custom_frag}"
fi
done
popd
# TODO: perform better consistency check on all commandline-given parameters
# Determine choice of nic MAC fixed assignment
if grep -w -q 'hvp_nicmacfix' /proc/cmdline ; then
nicmacfix="true"
fi
# Determine choice of skipping custom packages installation
if grep -w -q 'hvp_orthodox' /proc/cmdline ; then
orthodox_mode="true"
fi
# Determine choice of allowing snapshot/nightly oVirt packages installation
if grep -w -q 'hvp_ovirt_nightly' /proc/cmdline ; then
ovirt_nightly_mode="true"
fi
# Determine choice of using VDO
if grep -w -q 'hvp_use_vdo' /proc/cmdline ; then
use_vdo="true"
fi
# Determine node OS disk choice
given_nodeosdisk=$(sed -n -e 's/^.*hvp_nodeosdisk=\(\S*\).*$/\1/p' /proc/cmdline)
# Note: we want the devices list alphabetically ordered anyway
all_devices="$(list-harddrives | egrep -v '^(fd|sr)[[:digit:]]*[[:space:]]' | awk '{print $1}' | sort)"
# No indication on node OS disk choice: use default choice
if [ -z "${given_nodeosdisk}" ]; then
given_nodeosdisk="${default_nodeosdisk}"
fi
if [ -b "/dev/${given_nodeosdisk}" ]; then
# If the given string is a device name then use that
disk_device_name="${given_nodeosdisk}"
disk_device_size=$(blockdev --getsize64 /dev/${disk_device_name})
else
# If the given string is a generic indication then find the proper device
case "${given_nodeosdisk}" in
first)
disk_device_name=$(echo "${all_devices}" | head -1)
disk_device_size=$(blockdev --getsize64 /dev/${disk_device_name})
;;
last)
disk_device_name=$(echo "${all_devices}" | tail -1)
disk_device_size=$(blockdev --getsize64 /dev/${disk_device_name})
;;
*)
# Note: we allow for choosing either the first smallest device (default, if only "smallest" has been indicated) or the last one
case "${given_nodeosdisk}" in
last-smallest)
# If we want the last of the smallests then keep changing selected device even for the same size
comparison_logic="-le"
;;
*)
# In case of unrecognized/unsupported indication use smallest as default choice
# If we want the first of the smallests then change the selected device only if the size is strictly smaller
comparison_logic="-lt"
;;
esac
disk_device_name=""
for current_device in ${all_devices}; do
current_size=$(blockdev --getsize64 /dev/${current_device})
if [ -z "${disk_device_name}" ]; then
disk_device_name="${current_device}"
disk_device_size="${current_size}"
else
if [ ${current_size} ${comparison_logic} ${disk_device_size} ]; then
disk_device_name="${current_device}"
disk_device_size="${current_size}"
fi
fi
done
;;
esac
fi
# Determine cluster members number
given_node_count=$(sed -n -e 's/^.*hvp_nodecount=\(\S*\).*$/\1/p' /proc/cmdline)
if ! echo "${given_node_count}" | grep -q '^[[:digit:]]\+$' ; then
node_count="${default_node_count}"
else
node_count="${given_node_count}"
fi
# Fill in missing node names
for ((i=0;i<${node_count};i=i+1)); do
if [ -z "${node_name[${i}]}" ]; then
node_name[${i}]="node${i}"
fi
done
# Define number of active storage members
# Note: if we have three nodes only, then one (the last one) will be an all-arbiter no-I/O node
if [ "${node_count}" -eq 3 ]; then
active_storage_node_count="2"
else
active_storage_node_count="${node_count}"
fi
# Determine cluster member identity
my_index=$(sed -n -e 's/^.*hvp_nodeid=\(\S*\).*$/\1/p' /proc/cmdline)
if ! echo "${my_index}" | grep -q '^[[:digit:]]\+$' ; then
my_index="${default_node_index}"
fi
# Determine master node identity
given_master_index=$(sed -n -e 's/^.*hvp_masternodeid=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_master_index}" | grep -q '^[[:digit:]]\+$' ; then
master_index="${given_master_index}"
fi
# Determine cluster member names
given_names=$(sed -n -e 's/^.*hvp_nodename=\(\S*\).*$/\1/p' /proc/cmdline)
node_index="0"
for name in $(echo "${given_names}" | sed -e 's/,/ /g'); do
if echo "${name}" | grep -q '^[-[:alnum:]]\+$' ; then
node_name[${node_index}]="${name}"
node_index=$((node_index+1))
fi
done
# Determine installer name
given_installer_name=$(sed -n -e 's/^.*hvp_installername=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_installer_name}" | grep -q '^[-[:alnum:]]\+$' ; then
installer_name="${given_installer_name}"
fi
# Determine switch name
given_switch_name=$(sed -n -e 's/^.*hvp_switchname=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_switch_name}" | grep -q '^[-[:alnum:]]\+$' ; then
switch_name="${given_switch_name}"
fi
# Determine engine name
given_engine_name=$(sed -n -e 's/^.*hvp_enginename=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_engine_name}" | grep -q '^[-[:alnum:]]\+$' ; then
engine_name="${given_engine_name}"
fi
# Determine metrics server name
given_metrics_name=$(sed -n -e 's/^.*hvp_metricsname=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_metrics_name}" | grep -q '^[-[:alnum:]]\+$' ; then
metrics_name="${given_metrics_name}"
fi
# Determine storage name
given_storage_name=$(sed -n -e 's/^.*hvp_storagename=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_storage_name}" | grep -q '^[-[:alnum:]]\+$' ; then
storage_name="${given_storage_name}"
fi
# Determine root password
given_root_password=$(sed -n -e "s/^.*hvp_rootpwd=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_root_password}" ]; then
root_password="${given_root_password}"
fi
# Determine admin username
given_admin_username=$(sed -n -e "s/^.*hvp_adminname=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_admin_username}" ]; then
admin_username="${given_admin_username}"
fi
# Determine admin password
given_admin_password=$(sed -n -e "s/^.*hvp_adminpwd=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_admin_password}" ]; then
admin_password="${given_admin_password}"
fi
# Determine keyboard layout
given_keyboard_layout=$(sed -n -e "s/^.*hvp_kblayout=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_keyboard_layout}" ]; then
keyboard_layout="${given_keyboard_layout}"
fi
# Determine local timezone
given_local_timezone=$(sed -n -e "s/^.*hvp_timezone=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_local_timezone}" ]; then
local_timezone="${given_local_timezone}"
fi
# Determine oVirt version
given_ovirt_version=$(sed -n -e "s/^.*hvp_ovirt_version=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_ovirt_version}" ]; then
ovirt_version="${given_ovirt_version}"
fi
# Determine notification receiver email address
given_receiver_email=$(sed -n -e "s/^.*hvp_receiver_email=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_receiver_email}" ]; then
notification_receiver="${given_receiver_email}"
fi
# Determine node BMC IPs offset base
given_bmcs_offset=$(sed -n -e 's/^.*hvp_bmcs_offset=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_bmcs_offset}" | grep -q '^[[:digit:]]\+$' ; then
bmc_ip_offset="${given_bmcs_offset}"
fi
# Determine node IPs offset base
given_nodes_offset=$(sed -n -e 's/^.*hvp_nodes_offset=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_nodes_offset}" | grep -q '^[[:digit:]]\+$' ; then
node_ip_offset="${given_nodes_offset}"
fi
# Determine storage IPs offset base
given_storage_offset=$(sed -n -e 's/^.*hvp_storage_offset=\(\S*\).*$/\1/p' /proc/cmdline)
if echo "${given_storage_offset}" | grep -q '^[[:digit:]]\+$' ; then
storage_ip_offset="${given_storage_offset}"
fi
# Determine hostname
my_name="${node_name[${my_index}]}"
# Determine AD subdomain name
given_ad_subdomainname=$(sed -n -e "s/^.*hvp_ad_subdomainname=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_ad_subdomainname}" ]; then
ad_subdomain_prefix="${given_ad_subdomainname}"
fi
# Determine Gluster volume names
for volume in engine vmstore iso ctdb unixshare winshare blockshare backup; do
given_volume_name=$(sed -n -e "s/^.*hvp_${volume}_volumename=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_volume_name}" ]; then
gluster_vol_name["${volume}"]="${given_volume_name}"
fi
done
# Determine nameserver address
given_nameserver=$(sed -n -e "s/^.*hvp_nameserver=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_nameserver}" ]; then
my_nameserver="${given_nameserver}"
fi
# Determine forwarders addresses
given_forwarders=$(sed -n -e "s/^.*hvp_forwarders=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_forwarders}" ]; then
my_forwarders="${given_forwarders}"
fi
# Determine gateway address
given_gateway=$(sed -n -e "s/^.*hvp_gateway=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_gateway}" ]; then
my_gateway="${given_gateway}"
fi
# Determine network segments parameters
fixed_mgmt_bondmode="false"
unset my_ip
declare -A my_ip
for zone in "${!network[@]}" ; do
given_network_domain_name=$(sed -n -e "s/^.*hvp_${zone}_domainname=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_network_domain_name}" ]; then
domain_name["${zone}"]="${given_network_domain_name}"
fi
# Note: no bridge (vm accessibility) for Gluster network
if [ "${zone}" != "gluster" ]; then
given_network_bridge_name=$(sed -n -e "s/^.*hvp_${zone}_bridge=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
# Note: a bridge can be renamed but cannot be disabled if the physical network is present
if [ -n "${given_network_bridge_name}" ]; then
bridge_name["${zone}"]="${given_network_bridge_name}"
fi
fi
given_network_mtu=$(sed -n -e "s/^.*hvp_${zone}_mtu=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_network_mtu}" ]; then
mtu["${zone}"]="${given_network_mtu}"
fi
given_network_bondmode=$(sed -n -e "s/^.*hvp_${zone}_bondmode=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_network_bondmode}" ]; then
case "${given_network_bondmode}" in
lacp)
bondopts["${zone}"]="mode=802.3ad;xmit_hash_policy=layer2+3;miimon=100"
# Detect whether mgmt network bondmode has been explicitly specified
if [ "${zone}" = "mgmt" ]; then
fixed_mgmt_bondmode="true"
fi
;;
roundrobin)
# Note: roundrobin is supported only on GLUSTER network, otherwise we force activepassive
if [ "${zone}" = "gluster" ]; then
bondopts["${zone}"]="mode=balance-rr;miimon=100"
else
echo "Unsupported bonding mode (${given_network_bondmode}) for zone ${zone} - forcing activepassive" 1>&2
bondopts["${zone}"]="mode=active-backup;miimon=10"
fi
;;
activepassive)
bondopts["${zone}"]="mode=active-backup;miimon=100"
# Detect whether mgmt network bondmode has been explicitly specified
if [ "${zone}" = "mgmt" ]; then
fixed_mgmt_bondmode="true"
fi
;;
*)
# In case of unrecognized mode force activepassive
echo "Unrecognized bonding mode (${given_network_bondmode}) for zone ${zone} - forcing activepassive" 1>&2
bondopts["${zone}"]="mode=active-backup;miimon=100"
;;
esac
fi
given_network=$(sed -n -e "s/^.*hvp_${zone}=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
unset NETWORK NETMASK
eval $(ipcalc -s -n "${given_network}")
eval $(ipcalc -s -m "${given_network}")
if [ -n "${NETWORK}" -a -n "${NETMASK}" ]; then
network["${zone}"]="${NETWORK}"
netmask["${zone}"]="${NETMASK}"
fi
NETWORK=${network["${zone}"]}
NETMASK=${netmask["${zone}"]}
unset IPADDR
IPADDR=$(echo "${given_network}" | sed -n -e 's>^\([^/]*\)/.*$>\1>p')
if [ -n "${IPADDR}" -a "${IPADDR}" != "${NETWORK}" ]; then
my_ip["${zone}"]="${IPADDR}"
else
my_ip["${zone}"]=$(ipmat $(ipmat ${NETWORK} ${node_ip_offset} +) ${my_index} +)
fi
given_network_test_ip=$(sed -n -e "s/^.*hvp_${zone}_test_ip=\\(\\S*\\).*\$/\\1/p" /proc/cmdline)
if [ -n "${given_network_test_ip}" ]; then
test_ip["${zone}"]="${given_network_test_ip}"
fi
if [ -z "${test_ip[${zone}]}" ]; then
test_ip["${zone}"]=$(ipmat ${NETWORK} ${test_ip_offset} +)
fi
unset PREFIX
eval $(ipcalc -s -p "${NETWORK}" "${NETMASK}")
if [ "${PREFIX}" -ge 24 ]; then
reverse_domain_name["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $3,$2,$1}').in-addr.arpa
network_base["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $1,$2,$3}')
elif [ "${PREFIX}" -ge 16 ]; then
reverse_domain_name["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $2,$1}').in-addr.arpa
network_base["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $1,$2}')
elif [ "${PREFIX}" -ge 8 ]; then
reverse_domain_name["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $1}').in-addr.arpa
network_base["${zone}"]=$(echo ${NETWORK} | awk -F. 'BEGIN {OFS="."}; {print $1}')
fi
done
if [ -z "${my_gateway}" ]; then
my_gateway="${test_ip['mgmt']}"
fi
# Disable any interface configured by NetworkManager
# Note: NetworkManager may interfer with interface assignment autodetection logic below
# Note: interfaces will be explicitly activated again by our dynamically created network configuration fragment
for nic_device_name in $(nmcli -t device show | awk -F: '/^GENERAL\.DEVICE:/ {print $2}' | egrep -v '^(bonding_masters|lo|sit[0-9])$' | sort); do
if nmcli -t device show "${nic_device_name}" | grep -q '^GENERAL\.STATE:.*(connected)' ; then
nmcli device disconnect "${nic_device_name}"
ip addr flush dev "${nic_device_name}"
ip link set mtu 1500 dev "${nic_device_name}"
fi
done
for connection_name in $(nmcli -t connection show | awk -F: '{print $1}' | sort); do
nmcli connection delete "${connection_name}"
done
# Determine network interface assignment
# Note: unconnected nics will be disabled
unset nics
declare -A nics
for nic_name in $(ls /sys/class/net/ 2>/dev/null | egrep -v '^(bonding_masters|lo|sit[0-9])$' | sort); do
# Note: the file below will contain 1 for link up, 0 for link down or will result inaccessible for interface disabled
if [ "$(cat /sys/class/net/${nic_name}/carrier 2>/dev/null)" = "1" ]; then
ip addr flush dev "${nic_name}"
nic_assigned='false'
for zone in "${!network[@]}" ; do
# Note: check whether the desired MTU setting can be obtained or not - skip if it fails
ip link set mtu "${mtu[${zone}]}" dev "${nic_name}"
res=$?
effective_mtu=$(cat /sys/class/net/${nic_name}/mtu 2>/dev/null)
if [ ${res} -ne 0 -o "${effective_mtu}" != "${mtu[${zone}]}" ] ; then
ip addr flush dev "${nic_name}"
ip link set mtu 1500 dev "${nic_name}"
continue
fi
unset PREFIX
eval $(ipcalc -s -p "${network[${zone}]}" "${netmask[${zone}]}")
ip addr add "${my_ip[${zone}]}/${PREFIX}" dev "${nic_name}"
res=$?
if [ ${res} -ne 0 ] ; then
# There has been a problem in assigning the IP address - skip
ip addr flush dev "${nic_name}"
ip link set mtu 1500 dev "${nic_name}"
continue
fi
# Note: adding extra sleep and ping to work around possible hardware delays
sleep 2
ping -c 3 -w 8 -i 2 "${test_ip[${zone}]}" > /dev/null 2>&1
if ping -c 3 -w 8 -i 2 "${test_ip[${zone}]}" > /dev/null 2>&1 ; then
nics["${zone}"]="${nics[${zone}]} ${nic_name}"
nic_assigned='true'
ip addr flush dev "${nic_name}"
ip link set mtu 1500 dev "${nic_name}"
break
fi
ip addr flush dev "${nic_name}"