Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felixkrohn/f3fec7073b24375e168b83d7e2f22133 to your computer and use it in GitHub Desktop.
Save felixkrohn/f3fec7073b24375e168b83d7e2f22133 to your computer and use it in GitHub Desktop.
automatic kickstart centos9-stream @ OVH or SoYouStart or Kimsufi, with SoftRAID and LVM

How to install CentOS 9 STREAM on OVH/SoYouStart/Kimsufi

  • The idea behind this is to install your own custom OS from official/trusted sources, even on a cheap server where you don't have a SOL/IPMI graphical console.
  • connect to the OVH/SoYouStart/Kimsufi API and create a ipxe script under https://api.ovh.com/console/#/me/ipxeScript~POST, see centos9.ipxe below
  • boot your server from this netboot, and ping it to follow the process. If you can observe the webserver's logs you will se your server's IP pulling kernel and initrd with "iPXE" user agent, then it will start pinging, and retrieve the kickstart.cfg a bit later (with "curl" user agent). This is the moment when you could set your server back to "Boot from Hard Disk".
  • Also at this point you can connect to your server with SSH using the key/password set in the kickstart file. type tmux a to attach the install's tmux session and follow the progress. For debugging, check the logs in /tmp and those sent over syslog.

upstream documentation

hints for editing ipxe script

  • for debugging, add inst.syslog=: in order to forward all logs to another server where you run: while true; do nc -l -u -p ; done, the output will be displayed on stdout.
  • inst.ks param: host your kickstart file somewhere, anywhere. For debugging, ideally choose a location where you can watch the logs in order to see if it's being picked up.
  • add inst.nokill param to prevent the server from rebooting after a failed install - you can then connect via ssh to debug

kickstart hints

  • replace all the "xxx" by your own values
  • use python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())' to create your own crypted password string
  • I often had issues that anaconda wouldn't accept my partitioning because it somehow didn't consider the disks as empty event hough I specifically set "zerombr" and "clearpart" - better clear the partitioning table with sgdisk -Z /dev/sdX before launching the install. WARNING: this command is absolutely destructive and it won't ask for confirmation before zapping your partition tables.
#!ipxe
set kernel http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/vmlinuz
set initrd http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/initrd.img
# copy the above 2 files to your own webserver and adapt the links accordingly in order to be able to see from you webserver's logs if they're picked up correctly and follow the setup process from afar...
kernel ${kernel} initrd=initrd.img inst.gpt nameserver=213.186.33.99 inst.sshd inst.text inst.repo=http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os inst.ks=https://yourdomain/kickstart.cfg --hostname=foo.yourdomain rd.net.timeout.dhcp=30 ifname=eno1:a1:b2:c3:d4:e5:f6 ip=11.22.33.44::11.22.33.254:255.255.255.0:foo.yourdomain:eno1:none
initrd ${initrd}
boot
# only for RHEL:
#eula --agreed
#rhsm --activation-key=rhel9-ks --org=felixkrohn-priv
# System bootloader configuration
bootloader --append="nosplash crashkernel=auto" --location=mbr
# install-time ssh access
sshpw --username=USERNAME --sshkey [...]
sshpw --username=root --iscrypted $6$asdasdasd$[...]
# Use text mode install, no queries. will abort on error.
text --non-interactive
# Do not configure the X Window System
skipx
# localisation
keyboard --vckeymap=ch --xlayouts='ch'
lang en_US.UTF-8
# Installation logging level
#logging --level=warning --host=<OTHER_SERVER'S_IP> --port=54321
#logging --host=10.45.0.1 --port=514
# Network information, detailed and static
#network --bootproto=static --device=a1:b2:c3:d4:e5:f6 --gateway=11.22.33.254 --hostname=serverX.yourdomain --ip=11.22.33.44 --nameserver=213.186.33.99 --netmask=255.255.255.0 --ipv6=2001:41d0:aaaa:bbbb::1 --activate --ipv6gateway=2001:41d0:aaaa:bbff:00ff:00ff:00ff:00ff
# Network information, will use DHCP if not overrioden by kernel cmdline arguments
network --hostname=serverX.yourdomain
# not necessary as already set in above IPXE script.
#repo --name="AppStream" --baseurl=http://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/
#url --url="http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/"
# SELinux configuration
selinux --enforcing
# System services
firstboot --disable
services --enabled="sshd,chronyd,firewalld"
firewall --enabled --ssh --port=22:tcp,22222:tcp
# SSH keys on new system
sshkey --username=root "ecdsa-sha2-nistp521 [...]"
sshkey --username=<YOUR_USERNAME> "xxx"
## sshkey --username=root "xxx2" # set multiple keys in multiple lines
rootpw $6a$asdasdasdasd --iscrypted
# System timezone
timezone Europe/Berlin --utc
#--ntpservers=ntp.ovh.net
timesource --ntp-server ntp.ovh.net
user --groups=wheel,admin --name=YOUR_USERNAME
# Partition clearing information
ignoredisk --only-use=sda,sdb
clearpart --drives=sda,sdb --all --initlabel --disklabel=msdos
# System bootloader configuration
bootloader --append="nosplash crashkernel=auto" --location=mbr --boot-drive=sda
# Clear the Master Boot Record
zerombr
# Partition clearing information
clearpart --none --initlabel --disklabel=gpt
# Disk partitioning information
part /boot/efi --fstype="efi" --size=600 --fsoptions="umask=0077,shortname=winnt"
part raid.boot_a --fstype="mdmember" --ondisk=sda --size=1024
part raid.boot_b --fstype="mdmember" --ondisk=sdb --size=1024
part raid.root_a --fstype="mdmember" --ondisk=sda --size=20480
part raid.root_b --fstype="mdmember" --ondisk=sdb --size=20480
part raid.lvm_a --fstype="mdmember" --ondisk=sda --grow
part raid.lvm_b --fstype="mdmember" --ondisk=sdb --grow
#part /boot/efi2 --fstype="efi" --size=600 --fsoptions="umask=0077,shortname=winnt2" # this will crash anaconda... copy manually after install in order to be able to boot when sda breaks.
raid /boot --device=boot --fstype="xfs" --level=RAID1 --label=BOOT raid.boot_a raid.boot_b
raid / --device=root --fstype="xfs" --level=RAID1 --label=ROOT raid.root_a raid.root_b
raid pv.1 --device=pv00 --fstype="lvmpv" --level=RAID1 raid.lvm_a raid.lvm_b
part swap --fstype="swap" --size=1024
volgroup vg --pesize=4096 pv.1
logvol /home --fstype="xfs" --size=51200 --name=home --vgname=vg
# pre-install commands - leave a trace in webserver log to see when install starts
%pre
curl -kvI https://YOURDOMAIN/status:centos9-preinstall
%end
# post-install stuff - will be executed chroot'ed in new system
%post
touch /.autorelabel
curl -kvI https://YOURDOMAIN/status:centos9-postinstall
#rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
##echo -e "configure-and-quit=true\ndhcp=internal" > /etc/NetworkManager/conf.d/custom.conf
#semanage port -a -t ssh_port_t -p tcp 22222
#sed -i "s/^PermitRootLogin.*/#&\nPermitRootLogin without-password/g" /etc/ssh/sshd_config
#sed -i "s/^Port.*/#&\nPort 22222/g" /etc/ssh/sshd_config
#firewall-offline-cmd --service=ssh --add-port=22222/tcp
#firewall-offline-cmd --remove-service cockpit
sleep 7200 # give me some time to chec the install and disable netboot... connect via ssh and run "killall sleep" to avoid waiting.
%end
# package selection: remove everything not really necessary on a dedicated server. YMMV...
%packages
@^minimal-environment
@standard
+vim-enhanced
-NetworkManager-team
-blktrace
-bluez
-bpftool
-c-ares
-cockpit
-dnf-plugin-spacewalk
-dnf-plugin-subscription-manager
-fprintd-pam
-geolite2-city
-geolite2-country
-insights-client
-iwl100-firmware
-iwl1000-firmware
-iwl105-firmware
-iwl135-firmware
-iwl2000-firmware
-iwl2030-firmware
-iwl3160-firmware
-iwl3945-firmware
-iwl4965-firmware
-iwl5000-firmware
-iwl5150-firmware
-iwl6000-firmware
-iwl6000g2a-firmware
-iwl6050-firmware
-iwl7260-firmware
-kmod-kvdo
-ledmon
-libbasicobjects
-libcollection
-libdhash
-libini_config
-libldb
-libnfsidmap
-libpath_utils
-libref_array
-libsss_autofs
-libsss_certmap
-libsss_idmap
-libsss_nss_idmap
-libsss_sudo
-libstoragemgmt
-libtalloc
-libtdb
-libtevent
-mailcap
-man-pages
-mlocate
-nano
-nmap-ncat
-nvme-cli
-pinfo
-plymouth
-python3-dnf-plugin-spacewalk
-python3-rhn-client-tools
-realmd
-rhc
-rhn-client-tools
-rhn-setup
-rhnlib
-rhnsd
-rng-tools
-sos
-sssd
-sssd-client
-sssd-common
-sssd-kcm
-sssd-nfs-idmap
-subscription-manager
-subscription-manager-cockpit
-subscription-manager-plugin-container
-teamd
-time
-trousers
-trousers-lib
-usbutils
-vdo
-words
-xfsdump
-zip
%end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment