From 07e99017b1ad0fce56332a7dbd986cc80f806976 Mon Sep 17 00:00:00 2001 From: dave Date: Sun, 28 May 2017 16:38:17 -0700 Subject: [PATCH] Support for multiple sample templates --- README.md | 62 ++++++++++++-- add-iso.sh | 13 +++ iso_raws/.gitignore | 1 + main.html | 36 +++++--- main.py | 48 +++++++---- ks.default => samples/default/ks.default | 23 +++++- menu.default => samples/default/menu.default | 5 -- seed.default => samples/default/seed.default | 11 +++ samples/lvm/ks.default | 86 ++++++++++++++++++++ samples/lvm/menu.default | 24 ++++++ samples/lvm/seed.default | 40 +++++++++ 11 files changed, 308 insertions(+), 41 deletions(-) create mode 100755 add-iso.sh rename ks.default => samples/default/ks.default (97%) rename menu.default => samples/default/menu.default (77%) rename seed.default => samples/default/seed.default (99%) create mode 100644 samples/lvm/ks.default create mode 100644 samples/lvm/menu.default create mode 100644 samples/lvm/seed.default diff --git a/README.md b/README.md index e5aa7c0..c4c77c4 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,59 @@ -pip3 install -r requirements.txt -apt-get update && apt-get install -y genisoimage +kickstart-builder +================= + +Automated ISO builder for kickstart-based installation CDs + +Setup: +----- + +* Clone the repo +* Install requirements: + * `pip3 install -r requirements.txt` + * `apt-get install -y bsdtar genisoimage` +* Prepare at least one ISO (see below) +* Start it + * `python3 main.py` +* In your browser, visit http://127.0.0.1:8087/ + +Adding ISOs +----------- + +For each ISO you want to make available, create a subdirectory under iso_raws with a name matching you want to see in +the UI. Unpack the contents of an ISO into this directory. Some files and directories will need to be chmodded so they +can be written to. Refer to the example commands below: -To unpack ISOs: - -apt-get install -y bsdtar - +``` +cd iso_raws mkdir ubuntu-16.04.1-server-amd64 -cd mkdir ubuntu-16.04.1-server-amd64 -bsdtar xfp ../ubuntu-16.04.1-server-amd64.iso +cd ubuntu-16.04.1-server-amd64 +bsdtar xfp ~/Downloads/ubuntu-16.04.1-server-amd64.iso chmod 644 isolinux/txt.cfg isolinux/isolinux.bin chmod 755 preseed/ . +``` + +Alternatively, the script `add-iso.sh` can be used to add an ISO: + +``` +./add-iso.sh ~/Downloads/ubuntu-16.04.1-server-amd64.iso +``` + +Development Tips +---------------- + +In normal operation, the application loads templates and configs once on startup. If the `REFRESH` environmental +variable is set, it will reload the templates and configs on every page load: + +``` +REFRESH=1 python3 main.py +``` + +Additional config templates can be added under the "samples" directory. + + +Installing the `system-config-kickstart` provides a tool for generating Kickstart configs: + +``` +apt-get install system-config-kickstart +system-config-kickstart +``` diff --git a/add-iso.sh b/add-iso.sh new file mode 100755 index 0000000..9ad4c4a --- /dev/null +++ b/add-iso.sh @@ -0,0 +1,13 @@ +#!/bin/bash -ex + +ISO_PATH="$1" +ISO_NAME="$(basename $1 | sed -E 's/\.iso$//' )" + + +mkdir iso_raws/$ISO_NAME +cd iso_raws/$ISO_NAME + +bsdtar xfp $ISO_PATH + +chmod 644 isolinux/txt.cfg isolinux/isolinux.bin +chmod 755 preseed/ . diff --git a/iso_raws/.gitignore b/iso_raws/.gitignore index e69de29..72e8ffc 100644 --- a/iso_raws/.gitignore +++ b/iso_raws/.gitignore @@ -0,0 +1 @@ +* diff --git a/main.html b/main.html index 4521710..c05750d 100644 --- a/main.html +++ b/main.html @@ -9,6 +9,7 @@ } + Kickstart Builder @@ -19,15 +20,30 @@ Warning, these default configs will format drives without prompting!

-
-
- Base ISO: - -
+ +
+
+
+ Base ISO: + +
+
+
+
+ Sample configs: + + +
+
+

Menu Entries @@ -47,7 +63,7 @@

- +

diff --git a/main.py b/main.py index 3f7c1c8..71293f4 100755 --- a/main.py +++ b/main.py @@ -12,26 +12,42 @@ class ISOserver(object): self.data_dir = "./iso_raws" self.iso_selection = [i for i in os.listdir(self.data_dir) if not i.startswith(".")] self.builder_semaphores = {i: Semaphore() for i in self.iso_selection} - self._load_template() + self._load_templates() - def _load_template(self): - with open("./main.html") as template_f, \ - open("./menu.default") as menu_f, \ - open("./seed.default") as seed_f, \ - open("./ks.default") as ks_f: - self.template = Environment().from_string(template_f.read()).render(MENU_ENTRIES=menu_f.read(), - SEED_CONTENT=seed_f.read(), - KS_CONTENT=ks_f.read(), - ISOS=self.iso_selection) + def _load_templates(self): + with open("./main.html") as template_f: + self.template = Environment().from_string(template_f.read()) + + samples = os.listdir("samples") + self.samples = {} + + for item in samples: + self.samples[item] = {} + with open(os.path.join("samples", item, "menu.default")) as f: + self.samples[item]["menu"] = f.read() + with open(os.path.join("samples", item, "seed.default")) as f: + self.samples[item]["seed"] = f.read() + with open(os.path.join("samples", item, "ks.default")) as f: + self.samples[item]["ks"] = f.read() @cherrypy.expose - def index(self, refresh=False): - if refresh: - self._load_template() - yield(self.template) + def index(self, refresh=False, sample="default"): + if refresh or "REFRESH" in os.environ: + self._load_templates() + + yield(self.template.render(ISOS=self.iso_selection, + SAMPLES=self.samples.keys(), + MENU_ENTRIES=self.samples[sample]["menu"], + SEED_CONTENT=self.samples[sample]["seed"], + KS_CONTENT=self.samples[sample]["ks"], + current_sample=sample)) @cherrypy.expose - def getIso(self, menu_entries, seed_content, kickstart, base_image): + def process(self, menu_entries, seed_content, kickstart, base_image, action, sample): + if action == "Load": + assert sample in self.samples.keys() + raise cherrypy.HTTPRedirect("/?sample={}".format(sample)) + assert base_image in self.iso_selection cherrypy.response.headers['Content-Type'] = 'application/octet-stream' @@ -40,7 +56,7 @@ class ISOserver(object): builder = self.isoBuilder(menu_entries, seed_content, kickstart, base_image) return builder() - getIso._cp_config = {'response.stream': True} + process._cp_config = {'response.stream': True} def isoBuilder(self, menu_entries, seed_content, kickstart, base_image): datadir = os.path.join(self.data_dir, base_image) diff --git a/ks.default b/samples/default/ks.default similarity index 97% rename from ks.default rename to samples/default/ks.default index 1ed0035..e40fe2c 100644 --- a/ks.default +++ b/samples/default/ks.default @@ -1,39 +1,57 @@ #System language lang en_US + #Language modules to install langsupport en_US + #System keyboard keyboard us + #System mouse mouse + #System timezone timezone America/Los_Angeles + #Root password -rootpw chewy2 +rootpw ubuntu + #Initial user user --disabled + #Reboot after installation reboot + #Use text mode install text + #Install OS instead of upgrade install + #Use CDROM installation media cdrom + #System bootloader configuration bootloader --location=mbr + #Clear the Master Boot Record zerombr yes + #Partition clearing information clearpart --all --initlabel + #Disk partitioning information part / --fstype ext4 --size 1 --grow + #System authorization infomation auth --useshadow --enablemd5 + #Network information network --bootproto=dhcp --device=eth0 + #Firewall configuration firewall --disabled + #Do not configure the X Window System skipx @@ -41,6 +59,7 @@ skipx openssh-server vim htop + %post # Add arbitrary shell code to execute in the installer environment below here @@ -61,4 +80,4 @@ if [ -f /etc/firstboot ] ; then rm /etc/firstboot reboot fi -EOT \ No newline at end of file +EOT diff --git a/menu.default b/samples/default/menu.default similarity index 77% rename from menu.default rename to samples/default/menu.default index 8e7848c..7efcef8 100644 --- a/menu.default +++ b/samples/default/menu.default @@ -4,11 +4,6 @@ label install kernel /install/vmlinuz append file=/cdrom/preseed/ubuntu-server.seed vga=788 initrd=/install/initrd.gz quiet -- -label webseed - menu label ^Install from web seed - kernel /install/vmlinuz - append initrd=/install/initrd.gz ks=http://ubuntuseed/webseed/webseed/ks.cfg url=http://ubuntuseed/webseed/webseed/ubuntu.seed -- - label on_disk_kickstart menu label ^Install from kickstart + seed kernel /install/vmlinuz diff --git a/seed.default b/samples/default/seed.default similarity index 99% rename from seed.default rename to samples/default/seed.default index baba392..7401018 100644 --- a/seed.default +++ b/samples/default/seed.default @@ -1,29 +1,40 @@ # Always install the virtual kernel. d-i base-installer/kernel/override-image string linux-virtual + # Don't even install the standard task. tasksel tasksel/skip-tasks string standard + # Only install basic language packs. Let tasksel ask about tasks. d-i pkgsel/language-pack-patterns string + # No language support packages. d-i pkgsel/install-language-support boolean false + # Only ask the UTC question if there are other operating systems installed. d-i clock-setup/utc-auto boolean true + # Use UTC time d-i time/zone string UTC + # Verbose output and no boot splash screen. d-i debian-installer/quiet boolean false d-i debian-installer/splash boolean false + # Install the debconf oem-config frontend (if in OEM mode). d-i oem-config-udeb/frontend string debconf + # Wait for two seconds in grub d-i grub-installer/timeout string 2 + # Add the network and tasks oem-config steps by default. oem-config oem-config/steps multiselect language, timezone, keyboard, user, network, tasks # Bypass no swap warning d-i partman-basicfilesystems/no_swap boolean false + # dont wait a long time for dhcp d-i netcfg/dhcp_timeout string 8 d-i netcfg/dhcpv6_timeout string 8 + # Allow weak passwords in installer d-i user-setup/allow-password-weak boolean true diff --git a/samples/lvm/ks.default b/samples/lvm/ks.default new file mode 100644 index 0000000..329c785 --- /dev/null +++ b/samples/lvm/ks.default @@ -0,0 +1,86 @@ +#System language +lang en_US + +#Language modules to install +langsupport en_US + +#System keyboard +keyboard us + +#System mouse +mouse + +#System timezone +timezone America/Los_Angeles + +#Root password +rootpw ubuntu + +#Initial user +user --disabled + +#Reboot after installation +reboot + +#Use text mode install +text + +#Install OS instead of upgrade +install + +#Use CDROM installation media +cdrom + +#System bootloader configuration +bootloader --location=mbr + +#Clear the Master Boot Record +zerombr yes + +#Partition clearing information +clearpart --all --initlabel + +#Disk partitioning information +part /boot --fstype ext2 --size=500 +part pv.01 --size=1 --grow +volgroup vg_root pv.01 +logvol / --vgname=vg_root --name=lv_root --grow + +#System authorization infomation +auth --useshadow --enablemd5 + +#Network information +network --bootproto=dhcp --device=eth0 + +#Firewall configuration +firewall --disabled + +#Do not configure the X Window System +skipx + +%packages +openssh-server +vim +htop + +%post +# Add arbitrary shell code to execute in the installer environment below here + +# run upgrades at first boot +touch /etc/firstboot +sed -i -e "s/exit\s*0//" /etc/rc.local +cat <> /etc/rc.local +# Below this line can be removed after first boot +if [ -f /etc/firstboot ] ; then + set +e + sed -i -E "s/^PermitRootLogin .+/PermitRootLogin yes/" /etc/ssh/sshd_config + apt-get update + apt-get dist-upgrade -y + # Install new kernel on 14.04 + #apt-get install -y linux-generic-lts-xenial open-vm-tools + # revert to upstart on 16.04 + #apt-get install -y upstart-sysv + rm /etc/firstboot + reboot +fi +EOT diff --git a/samples/lvm/menu.default b/samples/lvm/menu.default new file mode 100644 index 0000000..7efcef8 --- /dev/null +++ b/samples/lvm/menu.default @@ -0,0 +1,24 @@ +default install +label install + menu label ^Manual install + kernel /install/vmlinuz + append file=/cdrom/preseed/ubuntu-server.seed vga=788 initrd=/install/initrd.gz quiet -- + +label on_disk_kickstart + menu label ^Install from kickstart + seed + kernel /install/vmlinuz + append initrd=/install/initrd.gz ks=cdrom:/ks.cfg file=/cdrom/preseed/custom.seed -- + +label custom_seed + menu label ^Custom seed + kernel /install/vmlinuz + append initrd=/install/initrd.gz file=/cdrom/preseed/custom.seed -- + +label minimap_vm + menu label ^Minimal VM + kernel /install/vmlinuz + append initrd=/install/initrd.gz file=/cdrom/preseed/ubuntu-server-minimalvm.seed -- + +label memtest + menu label Test ^memory + kernel /install/mt86plus diff --git a/samples/lvm/seed.default b/samples/lvm/seed.default new file mode 100644 index 0000000..7401018 --- /dev/null +++ b/samples/lvm/seed.default @@ -0,0 +1,40 @@ +# Always install the virtual kernel. +d-i base-installer/kernel/override-image string linux-virtual + +# Don't even install the standard task. +tasksel tasksel/skip-tasks string standard + +# Only install basic language packs. Let tasksel ask about tasks. +d-i pkgsel/language-pack-patterns string + +# No language support packages. +d-i pkgsel/install-language-support boolean false + +# Only ask the UTC question if there are other operating systems installed. +d-i clock-setup/utc-auto boolean true + +# Use UTC time +d-i time/zone string UTC + +# Verbose output and no boot splash screen. +d-i debian-installer/quiet boolean false +d-i debian-installer/splash boolean false + +# Install the debconf oem-config frontend (if in OEM mode). +d-i oem-config-udeb/frontend string debconf + +# Wait for two seconds in grub +d-i grub-installer/timeout string 2 + +# Add the network and tasks oem-config steps by default. +oem-config oem-config/steps multiselect language, timezone, keyboard, user, network, tasks + +# Bypass no swap warning +d-i partman-basicfilesystems/no_swap boolean false + +# dont wait a long time for dhcp +d-i netcfg/dhcp_timeout string 8 +d-i netcfg/dhcpv6_timeout string 8 + +# Allow weak passwords in installer +d-i user-setup/allow-password-weak boolean true