[Ovirt-devel] [PATCH server] Rework the installer to add validation, file generation by templates, and default values
Bryan Kearney
bkearney at redhat.com
Thu Jan 8 16:40:41 UTC 2009
---
installer/bin/ovirt-installer | 421 ++++++++++++++++++++++-------------------
1 files changed, 226 insertions(+), 195 deletions(-)
diff --git a/installer/bin/ovirt-installer b/installer/bin/ovirt-installer
index 84604ef..7ae789d 100755
--- a/installer/bin/ovirt-installer
+++ b/installer/bin/ovirt-installer
@@ -22,252 +22,283 @@
require 'socket'
require 'fileutils'
+require 'erb'
-if File.exist?("/usr/sbin/sestatus")
-sestatus = `/usr/sbin/sestatus`
-if sestatus !~ /(Current mode: permissive|Current mode: disabled|SELinux status: disabled|SELinux status: permissive)/
-puts "SELinux enabled, please disable or set in permissive mode permanently by editing"
-puts "/etc/selinux/config and rebooting"
-exit
-end
-end
-
-FileUtils.mkdir_p("/usr/share/ace/appliances/ovirt")
-config_file = File.new("/usr/share/ace/appliances/ovirt/ovirt.pp", "w")
-config_file.write "import 'ovirt'\n"
-config_file.write "import 'firewall'\n\n"
-config_file.write "firewall::setup{'setup': status => 'disabled'}\n\n"
-
-mgmt_dev = ""
-prov_dev = ""
-
-dev_ct = 0
-net_devs = `hal-find-by-capability --capability net`
-net_devs.each_line{ |dev|
-dev_ct = dev_ct + 1
-}
-
-if dev_ct == 0
-puts "Unable to install without a network interface"
-exit
+#
+# Input output controls
+#
-else
-puts ""
-get_net_devs = `hal-find-by-capability --capability net`
-puts "Below are the detected networking devices\n\n"
-puts "mac address interface ip address"
-net_devs.each_line{ |dev|
-dev = dev.chomp
-interface = `hal-get-property --udi #{dev} --key net.interface`
-mac = `hal-get-property --udi #{dev} --key net.address`
-ip = `ifconfig #{interface}`
-ipaddr = ip.scan(/\s*inet addr:([\d.]+)/)
-puts mac.chop + " : " + interface.chop + " : " + ipaddr.to_s if interface.chop != "lo"
-}
+# Basic read logic
+def read_user_input(prompt)
+ print("\n#{prompt} ")
+ return gets.chomp
end
-if dev_ct > 1
-puts "\nDo you want separate management and provisioning networks? (y/n)"
-sep_networks = gets.chomp
-while sep_networks != "y" and sep_networks != "n"
-puts "Invalid choice"
-puts "Do you want separate management and provisioning networks? (y/n)"
-sep_networks = gets.chomp
+# prompt a user for a non-blank answer
+def prompt_for_answer(prompt, options={})
+ default = options[:default]
+ allow_blanks = options[:allow_blanks] ? options[:allow_blanks] : false
+ expression = options[:regex]
+ validate = !expression.nil?
+
+ if !default.nil?
+ prompt = "#{prompt} [#{default}]"
+ end
+
+ answer = read_user_input(prompt)
+ answer = default if (!default.nil? && answer == "")
+
+ if (answer == "" and ! allow_blanks)
+ puts("Plese enter a value")
+ answer = prompt_for_answer(prompt, options)
+ end
+
+ if (validate && answer !~ expression)
+ puts("That is not in the correct format")
+ answer = prompt_for_answer(prompt, options)
+ end
+
+ return answer
end
-if sep_networks == "y"
-while mgmt_dev == ""
-puts "Input your management interface (example: eth0)"
-mgmt_dev = gets.chomp
+# Allow a user to enter a Yes/No
+# And repeat the prompt until they do
+def prompt_yes_no(prompt, options={})
+ default = options[:default]
+
+ if default.nil?
+ prompt = "#{prompt} (y/n)"
+ else
+ prompt = "#{prompt} [#{default}]"
+ end
+ answer = read_user_input(prompt)
+ answer = default if (!default.nil? && answer == "")
+ answer = answer.downcase()
+ while answer != "y" and answer != "n"
+ puts("Invalid choice")
+ answer = read_user_input(prompt).downcase()
+ end
+
+ return answer
end
-while prov_dev == ""
-puts "Input your provisioning interface, this may also be your management interface (example: eth1)"
-prov_dev = gets.chomp
+#
+# The real script begins here
+#
+
+# These regular expressions will be used to
+# validate the user input
+IP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
+THREE_OCTETS = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
+FQDN = /(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)/
+IP_OR_FQDN = /(?=^.{1,254}$)(^((?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$)/
+OCTET = /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/
+
+# Print a friendly welcome message
+welcome = "This installer will configure the ovirt installation based on a series\n\
+of questions. When complete, you will be asked to install oVirt or\n\
+do the installation manually. Would you like to continue?"
+
+if (prompt_yes_no(welcome, :default => "y") == "n")
+ exit(0)
end
-elsif sep_networks == "n"
-while mgmt_dev == ""
-puts "Input your management/provisioning interface (example: eth1)"
-mgmt_dev = gets.chomp
-prov_dev = mgmt_dev
-end
+
+if File.exist?("/usr/sbin/sestatus")
+ sestatus = `/usr/sbin/sestatus`
+ if sestatus !~ /(Current mode: permissive|Current mode: disabled|SELinux status: disabled|SELinux status: permissive)/
+ puts "SELinux enabled, please disable or set in permissive mode permanently by editing"
+ puts "/etc/selinux/config and rebooting"
+ exit
+ end
end
-elsif dev_ct == 1
-while mgmt_dev == ""
-puts "\nOnly one networking device detected"
-puts "Input your management/provisioning interface (example: eth1)"
-mgmt_dev = gets.chomp
-prov_dev = mgmt_dev
-puts "Need Management interface"
+# Networking Configuration
+dev_ct = 0
+net_devs = `hal-find-by-capability --capability net`
+net_devs.each_line do |dev|
+ dev_ct = dev_ct + 1
end
+
+if dev_ct == 0
+ puts "Unable to install without a network interface"
+ exit
+else
+ puts ""
+ get_net_devs = `hal-find-by-capability --capability net`
+ puts "Below are the detected networking devices\n\n"
+ puts "mac address interface ip address"
+ net_devs.each_line do |dev|
+ dev = dev.chomp
+ interface = `hal-get-property --udi #{dev} --key net.interface`
+ mac = `hal-get-property --udi #{dev} --key net.address`
+ ip = `ifconfig #{interface}`
+ ipaddr = ip.scan(/\s*inet addr:([\d.]+)/)
+ puts mac.chop + " : " + interface.chop + " : " + ipaddr.to_s if interface.chop != "lo"
+ end
end
-puts "Enter the hostname of the oVirt management server (example: management.example.com)"
-ovirt_host = gets.chomp
+mgmt_dev = prompt_for_answer("Enter your management interface (example: eth0):")
+prov_dev = prompt_for_answer("Enter your provisioning interface, this may also be your management interface:", :default => mgmt_dev)
+
+sep_networks = (mgmt_dev == prov_dev) ? "n" : "y"
+
+ovirt_host = prompt_for_answer("Enter the hostname of the oVirt management server (example: management.example.com):", :regex => IP_OR_FQDN)
ipa_host = ovirt_host
-puts "\nUse this system's dns servers (y/n)"
+# DNS Configuration
+puts "\nThe following DNS servers were found:"
File.open('/etc/resolv.conf').each_line{ |line|
line = line.chomp
-puts line if line =~ /nameserver/ and line !~ /nameserver 127.0.0.1/
+ puts line if line =~ /nameserver/ and line !~ /nameserver 127.0.0.1/
}
-dns_servers = gets.chomp
-
-while dns_servers != "y" and dns_servers != "n"
-puts "Invalid choice"
-dns_servers = gets.chomp
-end
+dns_servers = prompt_yes_no("Use this systems's dns servers?")
mgmt_ip = `ifconfig #{mgmt_dev}`
mgmt_ipaddr= mgmt_ip.scan(/\s*inet addr:([\d.]+)/)
prov_ip = `ifconfig #{prov_dev}`
prov_ipaddr= prov_ip.scan(/\s*inet addr:([\d.]+)/)
-config_file.write "# dns configuration\n"
-config_file.write "$mgmt_ipaddr = '#{mgmt_ipaddr}'\n"
-config_file.write "$prov_ipaddr = '#{prov_ipaddr}'\n"
-config_file.write "$ovirt_host = '#{ovirt_host}'\n"
-config_file.write "$ipa_host = '#{ipa_host}'\n\n"
-
-if dns_servers == "n"
-config_file.write "dns::bundled{setup: mgmt_ipaddr=> $mgmt_ipaddr, prov_ipaddr=> $prov_ipaddr, mgmt_dev => '#{mgmt_dev}', prov_dev => '#{prov_dev}'}\n\n"
-end
-
if dns_servers == "y"
-config_file.write "dns::remote{setup: mgmt_ipaddr=> $mgmt_ipaddr, prov_ipaddr=> $prov_ipaddr, mgmt_dev => '#{mgmt_dev}', prov_dev => '#{prov_dev}'}\n\n"
-host_lookup = Socket.getaddrinfo(ipa_host,nil)
-hostip = host_lookup[1][3]
-if hostip.to_s != mgmt_ipaddr.to_s
-puts "Reverse dns lookup for #{ipa_host} failed, exiting"
-exit
-end
-end
-
-puts "Does you provisioning network already have dhcp? (y/n)"
-dhcp_setup = gets.chomp
-while dhcp_setup != "y" and dhcp_setup != "n"
-puts "Invalid choice"
-dhcp_setup = gets.chomp
+ host_lookup = Socket.getaddrinfo(ipa_host,nil)
+ hostip = host_lookup[1][3]
+ if hostip.to_s != mgmt_ipaddr.to_s
+ puts "Reverse dns lookup for #{ipa_host} failed, exiting"
+ exit
+ end
end
+# DHCP Configuration
+dhcp_setup = prompt_yes_no("Does your provisioning network already have dhcp?")
if dhcp_setup == "n"
-
-puts "DHCP Configuration\n"
-config_file.write "# dhcp configuration\n"
-dhcp_interface = prov_dev
-config_file.write "$dhcp_interface = '#{dhcp_interface}'\n"
-
-puts "Enter the first 3 octets of the dhcp network you wish to use (example: 192.168.50)"
-dhcp_network = gets.chomp
-config_file.write "$dhcp_network = '#{dhcp_network}'\n"
-
-puts "Enter the dhcp pool start address (example: 3)"
-dhcp_start = gets.chomp
-config_file.write "$dhcp_start = '#{dhcp_start}'\n"
-
-puts "Enter the dhcp pool end addess (example: 100)"
-dhcp_stop = gets.chomp
-config_file.write "$dhcp_stop = '#{dhcp_stop}'\n"
-
-puts "Enter the dhcp domain you wish to use (example: example.com)"
-dhcp_domain = gets.chomp
-config_file.write "$dhcp_domain = '#{dhcp_domain}'\n"
-
-config_file.write "$ntp_server = '#{mgmt_ipaddr}'\n\n"
-
-puts "Provide pxe/tftp capability? (y/n)"
-tftp_setup = gets.chomp
-
-if sep_networks == "y"
-prov_ip = `ifconfig #{prov_dev}`
-prov_dns_server = prov_ip.scan(/\s*inet addr:([\d.]+)/)
-config_file.write "$prov_dns_server = '#{prov_dns_server}'\n"
-
-puts "Enter the network gateway for your provisioning network (example: 192.168.50.254)"
-prov_network_gateway = gets.chomp
-config_file.write "$prov_network_gateway = '#{prov_network_gateway}'\n"
-end
+ dhcp_interface = prov_dev
+ dhcp_network = prompt_for_answer("Enter the first 3 octets of the dhcp network you wish to use (example: 192.168.50):", :regex => THREE_OCTETS)
+ dhcp_start = prompt_for_answer("Enter the dhcp pool start address (example: 3):", :regex => OCTET)
+ dhcp_stop = prompt_for_answer("Enter the dhcp pool end addess (example: 100):", :regex => OCTET)
+ dhcp_domain = prompt_for_answer("Enter the dhcp domain you wish to use (example: example.com):", :regex => IP_OR_FQDN)
+ tftp_setup = prompt_yes_no("Provide pxe/tftp capability?")
+
+ if sep_networks == "y"
+ prov_ip = `ifconfig #{prov_dev}`
+ prov_dns_server = prov_ip.scan(/\s*inet addr:([\d.]+)/)
+ prov_network_gateway = prompt_for_answer("Enter the network gateway for your provisioning network (example: 192.168.50.254):", :regex => IP_OR_FQDN)
+ end
end
# Cobbler Configuration
-puts "Do you have a cobbler already that you wish to use? (y/n)"
-cobbler_setup = gets.chomp
-
-while cobbler_setup != "y" and cobbler_setup != "n"
-puts "Invalid choice"
-cobbler_setup = gets.chomp
-end
-
-cobbler_config = "n"
+cobbler_setup = prompt_yes_no("Do you have a cobbler already that you wish to use?")
if cobbler_setup == "y"
-puts "Enter the hostname of your cobbler server"
-cobbler_hostname = gets.chomp
-puts "Enter your cobbler username"
-cobbler_user_name= gets.chomp
-puts "Enter your cobbler user password"
-cobbler_user_password = gets.chomp
-
+ cobbler_hostname = prompt_for_answer("Enter the hostname of your cobbler server:", :regex => IP_OR_FQDN)
elsif cobbler_setup == "n"
-cobbler_hostname = "localhost"
-puts "We will setup a cobbler instance, please provide the following information"
-puts "Enter your cobbler username"
-cobbler_user_name= gets.chomp
-puts "Enter your cobbler user password"
-cobbler_user_password = gets.chomp
+ cobbler_hostname = "localhost"
+ puts "\nWe will setup a cobbler instance, please provide the following information"
end
-config_file.write "# cobbler configuration\n"
-config_file.write "$cobbler_hostname = '#{cobbler_hostname}'\n"
-config_file.write "$cobbler_user_name = '#{cobbler_user_name}'\n"
-config_file.write "$cobbler_user_password = '#{cobbler_user_password}'\n\n"
-
+cobbler_user_name= prompt_for_answer("Enter your cobbler username:")
+cobbler_user_password = prompt_for_answer("Enter your cobbler user password:")
# Postgres Configuration
-puts "Enter a password for the ovirt postgres account"
db_username = "ovirt"
-db_password = gets.chomp
-config_file.write "# postgres configuration\n"
-config_file.write "$db_username = '#{db_username}'\n"
-config_file.write "$db_password = '#{db_password}'\n\n"
+db_password = prompt_for_answer("Enter a password for the ovirt postgres account:")
# FreeIPA Configuration
-config_file.write "# FreeIPA configuration\n"
-puts "Enter your realm name (example: example.com)"
-realm_name = gets.chomp
-config_file.write "$realm_name = '#{realm_name}'\n"
-puts "\nEnter an administrator password for FreeIPA "
-puts "*** This will also be you ovirtadmin password for the web management login ***\n\n"
-freeipa_password = gets.chomp
-config_file.write "$freeipa_password = '#{freeipa_password}'\n"
+realm_name = prompt_for_answer("Enter your realm name (example: example.com):", :regex => FQDN)
+
+freeipa_password = prompt_for_answer("NOTE: The following pasword will also be you ovirtadmin password for the web management login\n\
+Enter an administrator password for FreeIPA:")
ldap_dn = "cn=ipaConfig,cn=etc,"
ldap_dn_temp = realm_name.split(".")
ldap_dn_temp.each do |i|
-ldap_dn += "dc=#{i},"
+ ldap_dn += "dc=#{i},"
end
ldap_dn = ldap_dn.chop
-config_file.write "$ldap_dn = '#{ldap_dn}'\n\n"
-if cobbler_setup == "y"
-config_file.write "include cobbler::remote\n"
-elsif cobbler_setup == "n"
-config_file.write "include cobbler::bundled\n"
-end
+#
+# Use ERB to spit out the puppet file whcih is used by ace.
+#
-if dhcp_setup == "n"
-config_file.write "include dhcp::bundled\n"
-end
+# Create the template
+template = <<END_OF_TEMPLATE
+# Configurations script generated by ovirt-installer
+# at <%= Time.now().to_s() %>
+#
-if tftp_setup == "y"
-config_file.write "include tftp::bundled\n"
-end
+import 'ovirt'
+import 'firewall'
+firewall::setup{'setup':
+ status => 'disabled'
+}
+
+#DNS Configuration
+$mgmt_ipaddr = '<%= mgmt_ipaddr %>'
+$prov_ipaddr = '<%= prov_ipaddr %>'
+$ovirt_host = '<%= ovirt_host %>'
+$ipa_host = '<%= ipa_host %>'
+
+<% if dns_servers == "n" %>
+dns::bundled{setup:
+<% else %>
+dns::remote{
+<% end %>
+ mgmt_ipaddr=> $mgmt_ipaddr,
+ prov_ipaddr=> $prov_ipaddr,
+ mgmt_dev => '<%= mgmt_dev %>',
+ prov_dev => '<%= prov_dev %>'
+}
+
+# DHCP Configuration
+<% if dhcp_setup == "n" %>
+$dhcp_interface = '<%= dhcp_interface %>'
+$dhcp_network = '<%= dhcp_network %>'
+$dhcp_start = '<%= dhcp_start %>'
+$dhcp_stop = '<%= dhcp_stop %>'
+$dhcp_domain = '<%= dhcp_domain %>'
+$ntp_server = '<%= mgmt_ipaddr %>'
+<% if tftp_setup == "y" %>
+include tftp::bundled
+<% end %>
+<% if sep_networks == "y" %>
+$prov_dns_server = '<%= prov_dns_server %>'
+$prov_network_gateway = '<%= prov_network_gateway %>'
+<% end %>
+<% end %>
+
+
+# Cobbler configuration
+$cobbler_hostname = '<%= cobbler_hostname %>'
+$cobbler_user_name = '<%= cobbler_user_name %>'
+$cobbler_user_password = '<%= cobbler_user_password %>'
+
+# Postgres Configuration
+$db_username = '<%= db_username %>'
+$db_password = '<%= db_password %>'
+
+# FreeIPA configuration
+$realm_name = '<%= realm_name %>'
+$freeipa_password = '<%= freeipa_password %>'
+$ldap_dn = '<%= ldap_dn %>'
+
+<% if cobbler_setup == "n" %>
+include cobbler::bundled
+<% else %>
+include cobbler::remote
+<% end %>
+<% if dhcp_setup == "n" %>
+include dhcp::bundled
+<% end %>
+include postgres::bundled
+include freeipa::bundled
+include ovirt::setup
+END_OF_TEMPLATE
+
+# Generate the file and output it.
+FileUtils.mkdir_p("/usr/share/ace/appliances/ovirt")
+config_file = File.new("/usr/share/ace/appliances/ovirt/ovirt.pp", "w")
+config_file.write(ERB.new(template, 0, "%>").result)
+config_file.close()
-config_file.write "include postgres::bundled\n"
-config_file.write "include freeipa::bundled\n"
-config_file.write "include ovirt::setup\n"
-config_file.close
-puts "\n\nTo start the installation run: ace install ovirt"
+# Give a friendly reminder about what to do next
+puts "\nTo start the installation run: ace install ovirt"
--
1.6.0.6
More information about the ovirt-devel
mailing list