Work on modular installer
This commit is contained in:
		
							
								
								
									
										35
									
								
								install.seed.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								install.seed.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | ### | ||||||
|  | ### General definitions | ||||||
|  | ### | ||||||
|  |  | ||||||
|  | # The Debian release to use | ||||||
|  | debrelease="bullseye" | ||||||
|  |  | ||||||
|  | # The Debian mirror to use | ||||||
|  | debmirror="http://debian.mirror.rafal.ca/debian" | ||||||
|  |  | ||||||
|  | # Package list (installed during debootstrap) | ||||||
|  | debpkglist="lvm2,parted,gdisk,grub-pc,grub-efi-amd64,linux-image-amd64,sudo,vim,gpg,gpg-agent,aptitude,openssh-server,vlan,ifenslave,python2,python3,ca-certificates,ntp" | ||||||
|  |  | ||||||
|  | # Package list (installed in chroot) | ||||||
|  | suppkglist="firmware-linux,firmware-linux-nonfree,firmware-bnx2,firmware-bnx2x" | ||||||
|  |  | ||||||
|  | ### | ||||||
|  | ### Per-host definitions | ||||||
|  | ### | ||||||
|  |  | ||||||
|  | # The hostname of the system (set per-run) | ||||||
|  | target_hostname="HOSTNAME" | ||||||
|  |  | ||||||
|  | # The target disk (either path or model to find; path overrides model if set) | ||||||
|  | target_disk_path="/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0"  # Example: Dell BOSS on R6515 via explicit path | ||||||
|  | target_disk_model="DELLBOSS VD"                                     # Example: Dell BOSS on R6515 via model name | ||||||
|  |  | ||||||
|  | # SSH key method (usually tftp) | ||||||
|  | target_keys_method="tftp" | ||||||
|  |  | ||||||
|  | # SSH key path | ||||||
|  | target_keys_path="keys.txt" | ||||||
|  |  | ||||||
|  | # Deploy username | ||||||
|  | target_deploy_user="deploy" | ||||||
							
								
								
									
										654
									
								
								install.sh
									
									
									
									
									
								
							
							
						
						
									
										654
									
								
								install.sh
									
									
									
									
									
								
							| @@ -6,10 +6,13 @@ if [[ $( whoami ) != "root" ]]; then | |||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| logfile="/tmp/pvc-install.log" | iso_name="XXDATEXX" | ||||||
|  | target_deploy_user="XXDEPLOYUSERXX" | ||||||
|  |  | ||||||
| supported_debrelease="buster bullseye" | supported_debrelease="buster bullseye" | ||||||
| default_debrelease="buster" | default_debrelease="buster" | ||||||
| default_debmirror="http://debian.mirror.rafal.ca/debian" | default_debmirror="http://debian.mirror.rafal.ca/debian" | ||||||
|  |  | ||||||
| debpkglist="lvm2,parted,gdisk,grub-pc,grub-efi-amd64,linux-image-amd64,sudo,vim,gpg,gpg-agent,aptitude,openssh-server,vlan,ifenslave,python2,python3,ca-certificates,ntp" | debpkglist="lvm2,parted,gdisk,grub-pc,grub-efi-amd64,linux-image-amd64,sudo,vim,gpg,gpg-agent,aptitude,openssh-server,vlan,ifenslave,python2,python3,ca-certificates,ntp" | ||||||
| suppkglist="firmware-linux,firmware-linux-nonfree,firmware-bnx2,firmware-bnx2x" | suppkglist="firmware-linux,firmware-linux-nonfree,firmware-bnx2,firmware-bnx2x" | ||||||
|  |  | ||||||
| @@ -20,288 +23,374 @@ suppkglist="firmware-linux,firmware-linux-nonfree,firmware-bnx2,firmware-bnx2x" | |||||||
| # roles will overwrite it by default during configuration. | # roles will overwrite it by default during configuration. | ||||||
| root_password="hCb1y2PF" | root_password="hCb1y2PF" | ||||||
|  |  | ||||||
| clear | # Obtain the mode from the kernel command line | ||||||
|  | kernel_cmdline=$( cat /proc/cmdline ) | ||||||
|  | install_option="$( awk '{ | ||||||
|  |     for(i=1; i<=NF; i++) { | ||||||
|  |         if($i ~ /pvcinstall.preseed/) { | ||||||
|  |             print $i; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }' <<<"${kernel_cmdline}" | awk -F'=' '{ print $NF }' )" | ||||||
|  |  | ||||||
| echo "--------------------------------------------------------" | seed_config() { | ||||||
| echo "| PVC Node installer (XXDATEXX) |" |     echo "Hello ${1}" | ||||||
| echo "--------------------------------------------------------" |     seed_vlan="$( awk '{ | ||||||
| echo |         for(i=1; i<=NF; i++) { | ||||||
| echo "This LiveCD will install a PVC node base system ready for bootstrapping with 'pvc-ansible'." |             if($i ~ /pvcinstall.seed_vlan/) { | ||||||
| echo |                 print $i; | ||||||
| echo "* NOTE: If you make a mistake and need to restart the installer while answering" |             } | ||||||
| echo "        the questions below, you may do so by typing ^C to cancel the script," |         } | ||||||
| echo "        then re-running it by calling /install.sh in the resulting shell." |     }' <<<"${kernel_cmdline}" | awk -F'=' '{ print $NF }' )" | ||||||
| echo |     seed_host="$( awk '{ | ||||||
|  |         for(i=1; i<=NF; i++) { | ||||||
|  |             if($i ~ /pvcinstall.seed_host/) { | ||||||
|  |                 print $i; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }' <<<"${kernel_cmdline}" | awk -F'=' '{ print $NF }' )" | ||||||
|  |     seed_file="$( awk '{ | ||||||
|  |         for(i=1; i<=NF; i++) { | ||||||
|  |             if($i ~ /pvcinstall.seed_file/) { | ||||||
|  |                 print $i; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }' <<<"${kernel_cmdline}" | awk -F'=' '{ print $NF }' )" | ||||||
|  |  | ||||||
| echo "1) Please enter a fully-qualified hostname for the system. This should match the hostname" |     if [[ -n ${seed_vlan} ]]; then | ||||||
| echo "in the 'pvc-ansible' inventory." |         modprobe 8021q | ||||||
| while [[ -z ${target_hostname} ]]; do |  | ||||||
|     echo |  | ||||||
|     echo -n "> " |  | ||||||
|     read target_hostname |  | ||||||
|     if [[ -z ${target_hostname} ]]; then |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a hostname." |  | ||||||
|         continue |  | ||||||
|     fi |     fi | ||||||
|     echo |  | ||||||
| done |  | ||||||
|  |  | ||||||
| disks="$( |     # Perform DHCP on all interfaces to come online | ||||||
|     for disk in /dev/sd? /dev/nvme?n?; do |     for interface in $( ip address | grep '^[0-9]' | grep 'eno\|enp\|ens\|wlp' | awk '{ print $2 }' | tr -d ':' ); do | ||||||
|         if [[ ! -b ${disk} ]]; then |         ip link set ${interface} up | ||||||
|             continue |         if [[ -n ${seed_vlan} ]]; then | ||||||
|         fi |             vconfig add ${interface} ${seed_vlan} | ||||||
|         disk_data="$( fdisk -l ${disk} 2>/dev/null )" |             dhclient ${interface}.${seed_vlan} | ||||||
|         echo -n "${disk}" |  | ||||||
|         echo -en "\t$( grep "^Disk model:" <<<"${disk_data}" | awk '{ $1=""; print $0 }' )" |  | ||||||
|         echo -en "  $( grep "^Disk ${disk}:" <<<"${disk_data}" | awk '{ $1=""; $2="size:"; print $0 }' )" |  | ||||||
|         echo |  | ||||||
|     done |  | ||||||
| )" |  | ||||||
|  |  | ||||||
| echo "2) Please enter the disk to install the PVC base system to. This disk will be" |  | ||||||
| echo "wiped, an LVM PV created on it, and the system installed to this LVM." |  | ||||||
| echo "* NOTE: PVC requires a disk of at least 30GB to be installed to, and 100GB is the" |  | ||||||
| echo "recommended minimum size for optimal production partition sizes." |  | ||||||
| echo "* NOTE: For optimal performance, this disk should be high-performance flash (SSD, etc.)." |  | ||||||
| echo "* NOTE: This disk should be a RAID-1 volume configured in hardware, or a durable storage" |  | ||||||
| echo "device, maximum redundancy and resiliency." |  | ||||||
| echo |  | ||||||
| echo "Available disks:" |  | ||||||
| echo |  | ||||||
| echo -e "$( sed 's/\(.*\)/  \1/' <<<"${disks[@]}" )" |  | ||||||
| while [[ ! -b ${target_disk} ]]; do |  | ||||||
|     echo |  | ||||||
|     echo -n "> " |  | ||||||
|     read target_disk |  | ||||||
|     if [[ ! -b ${target_disk} ]]; then |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid target disk." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     blockdev_size="$(( $( blockdev --getsize64 ${target_disk} ) / 1024 / 1024 / 1024 - 1))" |  | ||||||
|     if [[ ${blockdev_size} -lt 30 ]]; then |  | ||||||
|         target_disk="" |  | ||||||
|         echo |  | ||||||
|         echo "The specified disk is too small (<30 GB) to use as a PVC system disk." |  | ||||||
|         echo "Please choose an alternative disk." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
| done |  | ||||||
|  |  | ||||||
| for interface in $( ip address | grep '^[0-9]' | grep 'eno\|enp\|ens\|wlp' | awk '{ print $2 }' | tr -d ':' ); do |  | ||||||
|     ip link set ${interface} up |  | ||||||
| done |  | ||||||
| sleep 2 |  | ||||||
| interfaces="$( |  | ||||||
|     ip address | grep '^[0-9]' | grep 'eno\|enp\|ens\|wlp' | awk '{ print $2"\t"$3 }' | tr -d ':' |  | ||||||
| )" |  | ||||||
| echo "3a) Please enter the primary network interface for external connectivity. If" |  | ||||||
| echo "no entries are shown here, ensure a cable is connected, then restart the" |  | ||||||
| echo "installer with ^C and '/install.sh'." |  | ||||||
| echo |  | ||||||
| echo "Available interfaces:" |  | ||||||
| echo |  | ||||||
| echo -e "$( sed 's/\(.*\)/  \1/' <<<"${interfaces[@]}" )" |  | ||||||
| while [[ -z ${target_interface} ]]; do |  | ||||||
|     echo |  | ||||||
|     echo -n "> " |  | ||||||
|     read target_interface |  | ||||||
|     if [[ -z ${target_interface} ]]; then |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid interface." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     if ! grep -qw "${target_interface}" <<<"${interfaces[@]}"; then |  | ||||||
|         target_interface="" |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid interface." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
| done |  | ||||||
|  |  | ||||||
| echo -n "3b) Is a tagged vLAN required for the primary network interface? [y/N] " |  | ||||||
| read vlans_req |  | ||||||
| if [[ ${vlans_req} == 'y' || ${vlans_req} == 'Y' ]]; then |  | ||||||
|     echo |  | ||||||
|     echo "Please enter the vLAN ID for the interface." |  | ||||||
|     while [[ -z ${vlan_id} ]]; do |  | ||||||
|         echo |  | ||||||
|         echo -n "> " |  | ||||||
|         read vlan_id |  | ||||||
|         if [[ -z ${vlan_id} ]]; then |  | ||||||
|             echo |  | ||||||
|             echo "Please enter a numeric vLAN ID." |  | ||||||
|             continue |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
|     echo |  | ||||||
| else |  | ||||||
|     vlan_id="" |  | ||||||
|     echo |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| echo "3c) Please enter the IP address, in CIDR format [X.X.X.X/YY], of the primary" |  | ||||||
| echo "network interface. Leave blank for DHCP configuration of the interface on boot." |  | ||||||
| echo |  | ||||||
| echo -n "> " |  | ||||||
| read target_ipaddr |  | ||||||
| if [[ -n ${target_ipaddr} ]]; then |  | ||||||
|     target_netformat="static" |  | ||||||
|     echo |  | ||||||
|     echo "3d) Please enter the default gateway IP address of the primary" |  | ||||||
|     echo "network interface." |  | ||||||
|     while [[ -z ${target_defgw} ]]; do |  | ||||||
|         echo |  | ||||||
|         echo -n "> " |  | ||||||
|         read target_defgw |  | ||||||
|         if [[ -z ${target_defgw} ]]; then |  | ||||||
|             echo |  | ||||||
|             echo "Please enter a default gateway; the installer requires Internet access." |  | ||||||
|             continue |  | ||||||
|         fi |  | ||||||
|         echo |  | ||||||
|     done |  | ||||||
| else |  | ||||||
|     target_netformat="dhcp" |  | ||||||
|     echo |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| echo -n "Bringing up primary network interface in ${target_netformat} mode... " |  | ||||||
| case ${target_netformat} in |  | ||||||
|     'static') |  | ||||||
|         if [[ -n ${vlan_id} ]]; then |  | ||||||
|             modprobe 8021q >&2 |  | ||||||
|             vconfig add ${target_interface} ${vlan_id} >&2 |  | ||||||
|             vlan_interface=${target_interface}.${vlan_id} |  | ||||||
|             ip link set ${target_interface} up >&2 || true |  | ||||||
|             ip link set ${vlan_interface} up >&2 || true |  | ||||||
|             ip address add ${target_ipaddr} dev ${vlan_interface} >&2 || true |  | ||||||
|             ip route add default via ${target_defgw} >&2 || true |  | ||||||
|             formatted_ipaddr="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Host address/{ print $NF }' )" |  | ||||||
|             formatted_netmask="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Network mask/{ print $NF }' )" |  | ||||||
|             target_interfaces_block="auto ${vlan_interface}\niface ${vlan_interface} inet ${target_netformat}\n\tvlan_raw_device ${target_interface}\n\taddress ${formatted_ipaddr}\n\tnetmask ${formatted_netmask}\n\tgateway ${target_defgw}" |  | ||||||
|             real_interface="${vlan_interface}" |  | ||||||
|         else |         else | ||||||
|             ip link set ${target_interface} up >&2 || true |             dhclient ${interface} | ||||||
|             ip address add ${target_ipaddr} dev ${target_interface} >&2 || true |  | ||||||
|             ip route add default via ${target_defgw} >&2 || true |  | ||||||
|             formatted_ipaddr="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Host address/{ print $NF }' )" |  | ||||||
|             formatted_netmask="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Network mask/{ print $NF }' )" |  | ||||||
|             target_interfaces_block="auto ${target_interface}\niface ${target_interface} inet ${target_netformat}\n\taddress ${formatted_ipaddr}\n\tnetmask ${formatted_netmask}\n\tgateway ${target_defgw}" |  | ||||||
|             real_interface="${target_interface}" |  | ||||||
|         fi |         fi | ||||||
|         cat <<EOF >/etc/resolv.conf |     done | ||||||
|  |  | ||||||
|  |     # Fetch the seed config | ||||||
|  |     tftp -m binary "${seed_host}" -c get "${seed_file}" /tmp/install.seed | ||||||
|  |  | ||||||
|  |     . /tmp/install.seed | ||||||
|  |  | ||||||
|  |     # Handle the target disk | ||||||
|  |     if [[ -n ${target_disk_path} ]]; then | ||||||
|  |         target_disk="$( readlink ${target_disk_path} )" | ||||||
|  |         if [[ ! -b ${target_disk} ]]; then | ||||||
|  |             echo "Invalid disk!" | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     else | ||||||
|  |         # Find the (first) disk with the given model | ||||||
|  |         for disk in /dev/sd?; do | ||||||
|  |             disk_model="$( fdisk -l ${disk} | grep 'Disk model:' | sed 's/Disk model: //g' )" | ||||||
|  |             if [[ ${disk_model} == ${target_disk_model} ]]; then | ||||||
|  |                 target_disk="${disk}" | ||||||
|  |                 break | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | interactive_config() { | ||||||
|  |     clear | ||||||
|  |      | ||||||
|  |     echo "-----------------------------------------------------" | ||||||
|  |     echo "| PVC Node installer (${iso_name}) |" | ||||||
|  |     echo "-----------------------------------------------------" | ||||||
|  |     echo | ||||||
|  |     echo "This LiveCD will install a PVC node base system ready for bootstrapping with 'pvc-ansible'." | ||||||
|  |     echo | ||||||
|  |     echo "* NOTE: If you make a mistake and need to restart the installer while answering" | ||||||
|  |     echo "        the questions below, you may do so by typing ^C to cancel the script," | ||||||
|  |     echo "        then re-running it by calling /install.sh in the resulting shell." | ||||||
|  |     echo | ||||||
|  |      | ||||||
|  |     echo "1) Please enter a fully-qualified hostname for the system. This should match the hostname" | ||||||
|  |     echo "in the 'pvc-ansible' inventory." | ||||||
|  |     while [[ -z ${target_hostname} ]]; do | ||||||
|  |         echo | ||||||
|  |         echo -n "> " | ||||||
|  |         read target_hostname | ||||||
|  |         if [[ -z ${target_hostname} ]]; then | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a hostname." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         echo | ||||||
|  |     done | ||||||
|  |      | ||||||
|  |     disks="$( | ||||||
|  |         for disk in /dev/sd? /dev/nvme?n?; do | ||||||
|  |             if [[ ! -b ${disk} ]]; then | ||||||
|  |                 continue | ||||||
|  |             fi | ||||||
|  |             disk_data="$( fdisk -l ${disk} 2>/dev/null )" | ||||||
|  |             echo -n "${disk}" | ||||||
|  |             echo -en "\t$( grep "^Disk model:" <<<"${disk_data}" | awk '{ $1=""; print $0 }' )" | ||||||
|  |             echo -en "  $( grep "^Disk ${disk}:" <<<"${disk_data}" | awk '{ $1=""; $2="size:"; print $0 }' )" | ||||||
|  |             echo | ||||||
|  |         done | ||||||
|  |     )" | ||||||
|  |      | ||||||
|  |     echo "2) Please enter the disk to install the PVC base system to. This disk will be" | ||||||
|  |     echo "wiped, an LVM PV created on it, and the system installed to this LVM." | ||||||
|  |     echo "* NOTE: PVC requires a disk of at least 30GB to be installed to, and 100GB is the" | ||||||
|  |     echo "recommended minimum size for optimal production partition sizes." | ||||||
|  |     echo "* NOTE: For optimal performance, this disk should be high-performance flash (SSD, etc.)." | ||||||
|  |     echo "* NOTE: This disk should be a RAID-1 volume configured in hardware, or a durable storage" | ||||||
|  |     echo "device, maximum redundancy and resiliency." | ||||||
|  |     echo | ||||||
|  |     echo "Available disks:" | ||||||
|  |     echo | ||||||
|  |     echo -e "$( sed 's/\(.*\)/  \1/' <<<"${disks[@]}" )" | ||||||
|  |     while [[ ! -b ${target_disk} ]]; do | ||||||
|  |         echo | ||||||
|  |         echo -n "> " | ||||||
|  |         read target_disk | ||||||
|  |         if [[ ! -b ${target_disk} ]]; then | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid target disk." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         blockdev_size="$(( $( blockdev --getsize64 ${target_disk} ) / 1024 / 1024 / 1024 - 1))" | ||||||
|  |         if [[ ${blockdev_size} -lt 30 ]]; then | ||||||
|  |             target_disk="" | ||||||
|  |             echo | ||||||
|  |             echo "The specified disk is too small (<30 GB) to use as a PVC system disk." | ||||||
|  |             echo "Please choose an alternative disk." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         echo | ||||||
|  |     done | ||||||
|  |      | ||||||
|  |     for interface in $( ip address | grep '^[0-9]' | grep 'eno\|enp\|ens\|wlp' | awk '{ print $2 }' | tr -d ':' ); do | ||||||
|  |         ip link set ${interface} up | ||||||
|  |     done | ||||||
|  |     sleep 2 | ||||||
|  |     interfaces="$( | ||||||
|  |         ip address | grep '^[0-9]' | grep 'eno\|enp\|ens\|wlp' | awk '{ print $2"\t"$3 }' | tr -d ':' | ||||||
|  |     )" | ||||||
|  |     echo "3a) Please enter the primary network interface for external connectivity. If" | ||||||
|  |     echo "no entries are shown here, ensure a cable is connected, then restart the" | ||||||
|  |     echo "installer with ^C and '/install.sh'." | ||||||
|  |     echo | ||||||
|  |     echo "Available interfaces:" | ||||||
|  |     echo | ||||||
|  |     echo -e "$( sed 's/\(.*\)/  \1/' <<<"${interfaces[@]}" )" | ||||||
|  |     while [[ -z ${target_interface} ]]; do | ||||||
|  |         echo | ||||||
|  |         echo -n "> " | ||||||
|  |         read target_interface | ||||||
|  |         if [[ -z ${target_interface} ]]; then | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid interface." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         if ! grep -qw "${target_interface}" <<<"${interfaces[@]}"; then | ||||||
|  |             target_interface="" | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid interface." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         echo | ||||||
|  |     done | ||||||
|  |      | ||||||
|  |     echo -n "3b) Is a tagged vLAN required for the primary network interface? [y/N] " | ||||||
|  |     read vlans_req | ||||||
|  |     if [[ ${vlans_req} == 'y' || ${vlans_req} == 'Y' ]]; then | ||||||
|  |         echo | ||||||
|  |         echo "Please enter the vLAN ID for the interface." | ||||||
|  |         while [[ -z ${vlan_id} ]]; do | ||||||
|  |             echo | ||||||
|  |             echo -n "> " | ||||||
|  |             read vlan_id | ||||||
|  |             if [[ -z ${vlan_id} ]]; then | ||||||
|  |                 echo | ||||||
|  |                 echo "Please enter a numeric vLAN ID." | ||||||
|  |                 continue | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |         echo | ||||||
|  |     else | ||||||
|  |         vlan_id="" | ||||||
|  |         echo | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     echo "3c) Please enter the IP address, in CIDR format [X.X.X.X/YY], of the primary" | ||||||
|  |     echo "network interface. Leave blank for DHCP configuration of the interface on boot." | ||||||
|  |     echo | ||||||
|  |     echo -n "> " | ||||||
|  |     read target_ipaddr | ||||||
|  |     if [[ -n ${target_ipaddr} ]]; then | ||||||
|  |         target_netformat="static" | ||||||
|  |         echo | ||||||
|  |         echo "3d) Please enter the default gateway IP address of the primary" | ||||||
|  |         echo "network interface." | ||||||
|  |         while [[ -z ${target_defgw} ]]; do | ||||||
|  |             echo | ||||||
|  |             echo -n "> " | ||||||
|  |             read target_defgw | ||||||
|  |             if [[ -z ${target_defgw} ]]; then | ||||||
|  |                 echo | ||||||
|  |                 echo "Please enter a default gateway; the installer requires Internet access." | ||||||
|  |                 continue | ||||||
|  |             fi | ||||||
|  |             echo | ||||||
|  |         done | ||||||
|  |     else | ||||||
|  |         target_netformat="dhcp" | ||||||
|  |         echo | ||||||
|  |     fi | ||||||
|  |      | ||||||
|  |     echo -n "Bringing up primary network interface in ${target_netformat} mode... " | ||||||
|  |     case ${target_netformat} in | ||||||
|  |         'static') | ||||||
|  |             if [[ -n ${vlan_id} ]]; then | ||||||
|  |                 modprobe 8021q >&2 | ||||||
|  |                 vconfig add ${target_interface} ${vlan_id} >&2 | ||||||
|  |                 vlan_interface=${target_interface}.${vlan_id} | ||||||
|  |                 ip link set ${target_interface} up >&2 || true | ||||||
|  |                 ip link set ${vlan_interface} up >&2 || true | ||||||
|  |                 ip address add ${target_ipaddr} dev ${vlan_interface} >&2 || true | ||||||
|  |                 ip route add default via ${target_defgw} >&2 || true | ||||||
|  |                 formatted_ipaddr="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Host address/{ print $NF }' )" | ||||||
|  |                 formatted_netmask="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Network mask/{ print $NF }' )" | ||||||
|  |                 target_interfaces_block="auto ${vlan_interface}\niface ${vlan_interface} inet ${target_netformat}\n\tvlan_raw_device ${target_interface}\n\taddress ${formatted_ipaddr}\n\tnetmask ${formatted_netmask}\n\tgateway ${target_defgw}" | ||||||
|  |                 real_interface="${vlan_interface}" | ||||||
|  |             else | ||||||
|  |                 ip link set ${target_interface} up >&2 || true | ||||||
|  |                 ip address add ${target_ipaddr} dev ${target_interface} >&2 || true | ||||||
|  |                 ip route add default via ${target_defgw} >&2 || true | ||||||
|  |                 formatted_ipaddr="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Host address/{ print $NF }' )" | ||||||
|  |                 formatted_netmask="$( sipcalc ${target_ipaddr} | grep -v '(' | awk '/Network mask/{ print $NF }' )" | ||||||
|  |                 target_interfaces_block="auto ${target_interface}\niface ${target_interface} inet ${target_netformat}\n\taddress ${formatted_ipaddr}\n\tnetmask ${formatted_netmask}\n\tgateway ${target_defgw}" | ||||||
|  |                 real_interface="${target_interface}" | ||||||
|  |             fi | ||||||
|  |             cat <<EOF >/etc/resolv.conf | ||||||
| nameserver 8.8.8.8 | nameserver 8.8.8.8 | ||||||
| EOF | EOF | ||||||
|     ;; |         ;; | ||||||
|     'dhcp') |         'dhcp') | ||||||
|         if [[ -n ${vlan_id} ]]; then |             if [[ -n ${vlan_id} ]]; then | ||||||
|             modprobe 8021q >&2 |                 modprobe 8021q >&2 | ||||||
|             vconfig add ${target_interface} ${vlan_id} &>/dev/null |                 vconfig add ${target_interface} ${vlan_id} &>/dev/null | ||||||
|             vlan_interface=${target_interface}.${vlan_id} |                 vlan_interface=${target_interface}.${vlan_id} | ||||||
|             target_interfaces_block="auto ${vlan_interface}\niface ${vlan_interface} inet ${target_netformat}\n\tvlan_raw_device${target_interface}" |                 target_interfaces_block="auto ${vlan_interface}\niface ${vlan_interface} inet ${target_netformat}\n\tvlan_raw_device${target_interface}" | ||||||
|             dhclient ${vlan_interface} >&2 |                 dhclient ${vlan_interface} >&2 | ||||||
|             real_interface="${vlan_interface}" |                 real_interface="${vlan_interface}" | ||||||
|         else |             else | ||||||
|             target_interfaces_block="auto ${target_interface}\niface ${target_interface} inet ${target_netformat}" |                 target_interfaces_block="auto ${target_interface}\niface ${target_interface} inet ${target_netformat}" | ||||||
|             dhclient ${target_interface} >&2 |                 dhclient ${target_interface} >&2 | ||||||
|             real_interface="${target_interface}" |                 real_interface="${target_interface}" | ||||||
|  |             fi | ||||||
|  |         ;; | ||||||
|  |     esac | ||||||
|  |     echo "done." | ||||||
|  |     echo | ||||||
|  |      | ||||||
|  |     echo -n "Waiting for networking to become ready... " | ||||||
|  |     while ! ping -q -c 1 8.8.8.8 &>/dev/null; do | ||||||
|  |         sleep 1 | ||||||
|  |     done | ||||||
|  |     echo "done." | ||||||
|  |     echo | ||||||
|  |      | ||||||
|  |     echo "4a) Please enter an alternate Debian release codename for the system if desired." | ||||||
|  |     echo "    Supported: ${supported_debrelease}" | ||||||
|  |     echo "    Default: ${default_debrelease}" | ||||||
|  |     while [[ -z ${debrelease} ]]; do | ||||||
|  |         echo | ||||||
|  |         echo -n "> " | ||||||
|  |         read debrelease | ||||||
|  |         if [[ -z ${debrelease} ]]; then | ||||||
|  |             debrelease="${default_debrelease}" | ||||||
|         fi |         fi | ||||||
|  |         if ! grep -qw "${debrelease}" <<<"${supported_debrelease}"; then | ||||||
|  |             debrelease="" | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid release." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         echo | ||||||
|  |     done | ||||||
|  |      | ||||||
|  |     echo "4b) Please enter an HTTP URL for an alternate Debian mirror if desired." | ||||||
|  |     echo "    Default: ${default_debmirror}" | ||||||
|  |     while [[ -z ${debmirror} ]]; do | ||||||
|  |         echo | ||||||
|  |         echo -n "> " | ||||||
|  |         read debmirror | ||||||
|  |         if [[ -z ${debmirror} ]]; then | ||||||
|  |             debmirror="${default_debmirror}" | ||||||
|  |         fi | ||||||
|  |         if ! wget -O /dev/null ${debmirror}/dists/${debrelease}/Release &>/dev/null; then | ||||||
|  |             debmirror="" | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid Debian mirror URL." | ||||||
|  |             continue | ||||||
|  |         fi | ||||||
|  |         echo | ||||||
|  |         echo "Repository mirror '${debmirror}' successfully validated." | ||||||
|  |         echo | ||||||
|  |     done | ||||||
|  |      | ||||||
|  |     target_keys_method="wget" | ||||||
|  |     echo "5) Please enter an HTTP URL containing a text list of SSH authorized keys to" | ||||||
|  |     echo "fetch. These keys will be allowed access to the deployment user 'XXDEPLOYUSER'" | ||||||
|  |     echo "via SSH." | ||||||
|  |     echo "" | ||||||
|  |     echo "Leave blank to bypass this and use a password instead." | ||||||
|  |     echo | ||||||
|  |     echo -n "> " | ||||||
|  |     read target_keys_path | ||||||
|  |     if [[ -z ${target_keys_path} ]]; then | ||||||
|  |         echo | ||||||
|  |         echo "No SSH keys URL specified. Falling back to password configuration." | ||||||
|  |         echo | ||||||
|  |         echo "5) Please enter a password (hidden), twice, for the deployment user '${target_deploy_user}'." | ||||||
|  |         while [[ -z "${target_password}" ]]; do | ||||||
|  |             echo | ||||||
|  |             echo -n "> " | ||||||
|  |             read -s target_password_1 | ||||||
|  |             echo | ||||||
|  |             echo -n "> " | ||||||
|  |             read -s target_password_2 | ||||||
|  |             echo | ||||||
|  |             if [[ -n "${target_password_1}" && "${target_password_1}" -eq "${target_password_2}" ]]; then | ||||||
|  |                 target_password="${target_password_1}" | ||||||
|  |             else | ||||||
|  |                 echo | ||||||
|  |                 echo "The specified passwords do not match or are empty." | ||||||
|  |             fi | ||||||
|  |         done | ||||||
|  |     else | ||||||
|  |         while ! wget -O /dev/null ${target_keys_path} &>/dev/null; do | ||||||
|  |             echo | ||||||
|  |             echo "Please enter a valid SSH keys URL." | ||||||
|  |             echo | ||||||
|  |             echo -n "> " | ||||||
|  |             read target_keys_path | ||||||
|  |         done | ||||||
|  |         echo | ||||||
|  |         echo "SSH key source '${target_keys_path}' successfully validated." | ||||||
|  |     fi | ||||||
|  |     echo | ||||||
|  | }     | ||||||
|  |  | ||||||
|  | case ${install_option} in | ||||||
|  |     on) | ||||||
|  |         seed_config | ||||||
|  |     ;; | ||||||
|  |     *) | ||||||
|  |         interactive_config | ||||||
|     ;; |     ;; | ||||||
| esac | esac | ||||||
| echo "done." |  | ||||||
| echo |  | ||||||
|  |  | ||||||
| echo -n "Waiting for networking to become ready... " |  | ||||||
| while ! ping -q -c 1 8.8.8.8 &>/dev/null; do |  | ||||||
|     sleep 1 |  | ||||||
| done |  | ||||||
| echo "done." |  | ||||||
| echo |  | ||||||
|  |  | ||||||
| echo "4a) Please enter an alternate Debian release codename for the system if desired." |  | ||||||
| echo "    Supported: ${supported_debrelease}" |  | ||||||
| echo "    Default: ${default_debrelease}" |  | ||||||
| while [[ -z ${debrelease} ]]; do |  | ||||||
|     echo |  | ||||||
|     echo -n "> " |  | ||||||
|     read debrelease |  | ||||||
|     if [[ -z ${debrelease} ]]; then |  | ||||||
|         debrelease="${default_debrelease}" |  | ||||||
|     fi |  | ||||||
|     if ! grep -qw "${debrelease}" <<<"${supported_debrelease}"; then |  | ||||||
|         debrelease="" |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid release." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
| done |  | ||||||
|  |  | ||||||
| echo "4b) Please enter an HTTP URL for an alternate Debian mirror if desired." |  | ||||||
| echo "    Default: ${default_debmirror}" |  | ||||||
| while [[ -z ${debmirror} ]]; do |  | ||||||
|     echo |  | ||||||
|     echo -n "> " |  | ||||||
|     read debmirror |  | ||||||
|     if [[ -z ${debmirror} ]]; then |  | ||||||
|         debmirror="${default_debmirror}" |  | ||||||
|     fi |  | ||||||
|     if ! wget -O /dev/null ${debmirror}/dists/${debrelease}/Release &>/dev/null; then |  | ||||||
|         debmirror="" |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid Debian mirror URL." |  | ||||||
|         continue |  | ||||||
|     fi |  | ||||||
|     echo |  | ||||||
|     echo "Repository mirror '${debmirror}' successfully validated." |  | ||||||
|     echo |  | ||||||
| done |  | ||||||
|  |  | ||||||
| echo "5) Please enter an HTTP URL containing a text list of SSH authorized keys to" |  | ||||||
| echo "fetch. These keys will be allowed access to the deployment user 'XXDEPLOYUSER'" |  | ||||||
| echo "via SSH." |  | ||||||
| echo "" |  | ||||||
| echo "Leave blank to bypass this and use a password instead." |  | ||||||
| echo |  | ||||||
| echo -n "> " |  | ||||||
| read target_keys_url |  | ||||||
| if [[ -z ${target_keys_url} ]]; then |  | ||||||
|     echo |  | ||||||
|     echo "No SSH keys URL specified. Falling back to password configuration." |  | ||||||
|     echo |  | ||||||
|     echo "5) Please enter a password (hidden), twice, for the deployment user 'XXDEPLOYUSERXX'." |  | ||||||
|     while [[ -z "${target_password}" ]]; do |  | ||||||
|         echo |  | ||||||
|         echo -n "> " |  | ||||||
|         read -s target_password_1 |  | ||||||
|         echo |  | ||||||
|         echo -n "> " |  | ||||||
|         read -s target_password_2 |  | ||||||
|         echo |  | ||||||
|         if [[ -n "${target_password_1}" && "${target_password_1}" -eq "${target_password_2}" ]]; then |  | ||||||
|             target_password="${target_password_1}" |  | ||||||
|         else |  | ||||||
|             echo |  | ||||||
|             echo "The specified passwords do not match or are empty." |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
| else |  | ||||||
|     while ! wget -O /dev/null ${target_keys_url} &>/dev/null; do |  | ||||||
|         echo |  | ||||||
|         echo "Please enter a valid SSH keys URL." |  | ||||||
|         echo |  | ||||||
|         echo -n "> " |  | ||||||
|         read target_keys_url |  | ||||||
|     done |  | ||||||
|     echo |  | ||||||
|     echo "SSH key source '${target_keys_url}' successfully validated." |  | ||||||
| fi |  | ||||||
| echo |  | ||||||
|  |  | ||||||
| titlestring_text="| Proceeding with installation of host '${target_hostname}'. |" | titlestring_text="| Proceeding with installation of host '${target_hostname}'. |" | ||||||
| titlestring_len="$(( $( wc -c <<<"${titlestring_text}" ) - 2 ))" | titlestring_len="$(( $( wc -c <<<"${titlestring_text}" ) - 2 ))" | ||||||
| @@ -314,6 +403,8 @@ echo | |||||||
| echo "LOGFILE: ${logfile}" | echo "LOGFILE: ${logfile}" | ||||||
| echo | echo | ||||||
|  |  | ||||||
|  | exit 0 | ||||||
|  |  | ||||||
| set -o errexit | set -o errexit | ||||||
| exec 1> >( tee -ia ${logfile} ) | exec 1> >( tee -ia ${logfile} ) | ||||||
| exec 2> >( tee -ia ${logfile} >/dev/null ) | exec 2> >( tee -ia ${logfile} >/dev/null ) | ||||||
| @@ -480,14 +571,21 @@ echo "done." | |||||||
|  |  | ||||||
| echo -n "Adding deployment user... " | echo -n "Adding deployment user... " | ||||||
| mv ${target}/home ${target}/var/home >&2 | mv ${target}/home ${target}/var/home >&2 | ||||||
| chroot ${target} useradd -u 200 -d /var/home/XXDEPLOYUSERXX -m -s /bin/bash -g operator -G sudo XXDEPLOYUSERXX >&2 | chroot ${target} useradd -u 200 -d /var/home/${target_deploy_user} -m -s /bin/bash -g operator -G sudo ${target_deploy_user} >&2 | ||||||
| chroot ${target} mkdir -p /var/home/XXDEPLOYUSERXX/.ssh | chroot ${target} mkdir -p /var/home/${target_deploy_user}/.ssh | ||||||
| if [[ -n ${target_keys_url} ]]; then | if [[ -n ${target_keys_path} ]]; then | ||||||
| wget -O ${target}/var/home/XXDEPLOYUSERXX/.ssh/authorized_keys ${target_keys_url} |     case ${target_keys_method} in | ||||||
| chroot ${target} chmod 0600 /var/home/XXDEPLOYUSERXX/.ssh/authorized_keys |         wget) | ||||||
| chroot ${target} chown -R XXDEPLOYUSERXX:operator /var/home/XXDEPLOYUSERXX |             wget -O ${target}/var/home/${target_deploy_user}/.ssh/authorized_keys ${target_keys_path} | ||||||
|  |         ;; | ||||||
|  |         tftp) | ||||||
|  |             tftp -m binary "${seed_host}" -c get "${target_keys_path}" ${target}/var/home/${target_deploy_user}/.ssh/authorized_keys | ||||||
|  |         ;; | ||||||
|  |     esac | ||||||
|  |     chroot ${target} chmod 0600 /var/home/${target_deploy_user}/.ssh/authorized_keys | ||||||
|  |     chroot ${target} chown -R ${target_deploy_user}:operator /var/home/${target_deploy_user} | ||||||
| else | else | ||||||
| echo "XXDEPLOYUSERXX:${target_password}" | chroot ${target} chpasswd >&2 |     echo "${target_deploy_user}:${target_password}" | chroot ${target} chpasswd >&2 | ||||||
| fi | fi | ||||||
| echo "done." | echo "done." | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								pxelinux.0
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								pxelinux.0
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user