Initial commit
This commit is contained in:
commit
1345d95889
|
@ -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/ .
|
|
@ -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 <<EOT >> /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
|
|
@ -0,0 +1,55 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<style>
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" type="text/css"/>
|
||||||
|
<title>Kickstart Builder</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="display-4">Ubuntu-Kickstart Builder</h1>
|
||||||
|
<p>Create bootable Ubuntu ISOs pre-configured with <a href="https://help.ubuntu.com/16.04/installation-guide/i386/ch04s06.html" target="_blank">Kickstart</a>.</p>
|
||||||
|
<div class="list-group">
|
||||||
|
<span class="list-group-item list-group-item-danger"> Warning, these default configs will format drives without prompting! </span>
|
||||||
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<form action="/getIso" method="post">
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<legend>Base ISO:</legend>
|
||||||
|
<select name="base_image" class="c-select">
|
||||||
|
{% for iso in ISOS: %}
|
||||||
|
<option value="{{ iso }}">{{ iso }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</fieldset>
|
||||||
|
<br />
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<legend>Menu Entries</legend>
|
||||||
|
<p>Selectable options displayed on the boot menu.</p>
|
||||||
|
<textarea class="form-control" name="menu_entries">{{ MENU_ENTRIES }}</textarea>
|
||||||
|
</fieldset>
|
||||||
|
<br />
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<legend>Seed Content</legend>
|
||||||
|
<p>Options to pass to the ubuntu installer. Install path: cdrom:/ks.cfg</p>
|
||||||
|
<textarea class="form-control" name="seed_content">{{ SEED_CONTENT }}</textarea>
|
||||||
|
</fieldset>
|
||||||
|
<br />
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<legend>Kickstart content</legend>
|
||||||
|
<p>Higher-level Kickstart installation options.</p>
|
||||||
|
<textarea class="form-control" name="kickstart">{{ KS_CONTENT }}</textarea>
|
||||||
|
</fieldset>
|
||||||
|
<br />
|
||||||
|
<input type="submit" value="Download!" class="btn btn-success">
|
||||||
|
<br /><br />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -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()
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue