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!
-
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