commit 1345d95889b97366e7450ecbefcaff6f7f622ce4 Author: dave Date: Sun May 28 15:41:02 2017 -0700 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5aa7c0 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +pip3 install -r requirements.txt +apt-get update && apt-get install -y genisoimage + + +To unpack ISOs: + +apt-get install -y bsdtar + +mkdir ubuntu-16.04.1-server-amd64 +cd mkdir ubuntu-16.04.1-server-amd64 +bsdtar xfp ../ubuntu-16.04.1-server-amd64.iso +chmod 644 isolinux/txt.cfg isolinux/isolinux.bin +chmod 755 preseed/ . diff --git a/iso_raws/.gitignore b/iso_raws/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/ks.default b/ks.default new file mode 100644 index 0000000..1ed0035 --- /dev/null +++ b/ks.default @@ -0,0 +1,64 @@ +#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 +#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 + +%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 \ No newline at end of file diff --git a/main.html b/main.html new file mode 100644 index 0000000..4521710 --- /dev/null +++ b/main.html @@ -0,0 +1,55 @@ + + + + + + + Kickstart Builder + + +
+

Ubuntu-Kickstart Builder

+

Create bootable Ubuntu ISOs pre-configured with Kickstart.

+
+ Warning, these default configs will format drives without prompting! +
+

+
+
+ Base ISO: + +
+
+
+ Menu Entries +

Selectable options displayed on the boot menu.

+ +
+
+
+ Seed Content +

Options to pass to the ubuntu installer. Install path: cdrom:/ks.cfg

+ +
+
+
+ Kickstart content +

Higher-level Kickstart installation options.

+ +
+
+ +

+
+ + + diff --git a/main.py b/main.py new file mode 100755 index 0000000..3f7c1c8 --- /dev/null +++ b/main.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 + +import cherrypy +from jinja2 import Environment +from subprocess import Popen, PIPE +from threading import Semaphore +import os + + +class ISOserver(object): + def __init__(self): + 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() + + 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) + + @cherrypy.expose + def index(self, refresh=False): + if refresh: + self._load_template() + yield(self.template) + + @cherrypy.expose + def getIso(self, menu_entries, seed_content, kickstart, base_image): + assert base_image in self.iso_selection + + cherrypy.response.headers['Content-Type'] = 'application/octet-stream' + cherrypy.response.headers['Content-Description'] = 'File Transfer' + cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="{}-custom.iso"'.format(base_image) + + builder = self.isoBuilder(menu_entries, seed_content, kickstart, base_image) + return builder() + getIso._cp_config = {'response.stream': True} + + def isoBuilder(self, menu_entries, seed_content, kickstart, base_image): + datadir = os.path.join(self.data_dir, base_image) + + def output(): + self.builder_semaphores[base_image].acquire() + + with open(os.path.join(datadir, "isolinux/txt.cfg"), "w") as f: + f.write(menu_entries) + with open(os.path.join(datadir, "preseed/custom.seed"), "w") as f: + f.write(seed_content) + with open(os.path.join(datadir, "ks.cfg"), "w") as f: + f.write(kickstart) + + try: + proc = Popen(['/usr/bin/mkisofs', '-b', 'isolinux/isolinux.bin', '-c', 'isolinux/boot.cat', + '-no-emul-boot', '-boot-load-size', '4', '-boot-info-table', '-J', '-R', '-V', + 'kickstart_linux', '.'], stdout=PIPE, cwd=datadir) + with proc.stdout as f: + while True: + data = f.read(8192) + if not data: + break + yield data + except Exception as e: + self.builder_semaphores[base_image].release() + raise + else: + self.builder_semaphores[base_image].release() + + print("Done!") + return output + + +if __name__ == '__main__': + + cherrypy.config.update({ + 'engine.autoreload_on': False, + 'tools.sessions.on': False, + 'tools.sessions.storage_type': 'ram', # 'file', + 'tools.sessions.timeout': 525600, + 'server.show.tracebacks': True, + 'server.socket_port': 8087, + 'server.thread_pool': 10, + 'server.socket_host': '0.0.0.0', + # 'tools.sessions.storage_path': './sessions/', + 'tools.sessions.locking': 'explicit' # cherrypy.session.acquire_lock() cherrypy.session.release_lock() + }) + + cherrypy.tree.mount(ISOserver(), '/', config={ + '/': {}, + '/static': { # 'tools.staticdir.on': True, + # 'tools.staticdir.dir': ./static/" + } + }) + cherrypy.engine.start() + cherrypy.engine.block() diff --git a/menu.default b/menu.default new file mode 100644 index 0000000..8e7848c --- /dev/null +++ b/menu.default @@ -0,0 +1,29 @@ +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 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 + 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/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e2adc50 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +appdirs==1.4.3 +cheroot==5.5.0 +CherryPy==10.2.2 +Jinja2==2.9.6 +MarkupSafe==1.0 +packaging==16.8 +portend==1.8 +pyparsing==2.2.0 +pytz==2017.2 +six==1.10.0 +tempora==1.7 diff --git a/seed.default b/seed.default new file mode 100644 index 0000000..baba392 --- /dev/null +++ b/seed.default @@ -0,0 +1,29 @@ +# 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