You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

127 lines
3.6 KiB

package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"text/template"
"github.com/teran-mckinney/burnpaste"
)
type preseedArgs struct {
SSHKEY string
CRYPTED_PASSWORD string
}
type ipxescriptArgs struct {
HOSTNAME string
MIRROR string
PRESEED string
PRESEED_CHECKSUM string
}
const debian_preseed = `d-i debian-installer/locale string en_US
d-i keyboard-configuration/xkb-keymap select us
d-i clock-setup/utc boolean true
d-i time/zone string Etc/UTC
d-i clock-setup/ntp boolean false
# https://superuser.com/a/920957
d-i partman-basicfilesystems/no_swap boolean false
d-i partman-auto/expert_recipe string myroot :: 1000 50 -1 ext4 \
$primary{ } $bootable{ } method{ format } \
format{ } use_filesystem{ } filesystem{ ext4 } \
options/noatime{ noatime } options/nodiratime{ nodiratime } \
mountpoint{ / } \
.
d-i partman-auto/choose_recipe select myroot
d-i partman-auto/method string regular
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i apt-setup/non-free boolean false
d-i apt-setup/contrib boolean false
d-i passwd/root-login boolean true
d-i passwd/root-password-crypted password {{.CRYPTED_PASSWORD}}
d-i passwd/make-user boolean false
d-i base-installer/install-recommends boolean false
tasksel tasksel/first multiselect standard
popularity-contest popularity-contest/participate boolean false
d-i debian-installer/add-kernel-opts string net.ifnames=0
d-i grub-installer/only_debian boolean false
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev string default
d-i finish-install/reboot_in_progress note
d-i preseed/late_command string apt-install openssh-server; in-target mkdir /root/.ssh; in-target sh -c "echo '{{.SSHKEY}}' > /root/.ssh/authorized_keys"; in-target systemctl enable serial-getty@ttyS0.service
`
const debian_ipxescript = `#!ipxe
dhcp
set mirror {{.MIRROR}}
kernel ${mirror}/linux console=ttyS0,115200n8 net.ifnames=0 netcfg/choose_interface=eth0 initrd=initrd.gz auto=true priority=critical hostname={{.HOSTNAME}} auto url={{.PRESEED}} preseed-md5={{.PRESEED_CHECKSUM}}
initrd ${mirror}/initrd.gz
boot
`
func debianPreseed(sshKey, burnpaste_endpoint, hostname, mirror string) (response IPXE, err error) {
// burnpaste_endpoint is a running burnpaste instance to store our preseed data.
var return_script bytes.Buffer
var rendered_preseed bytes.Buffer
if err = validateSSHKey(sshKey); err != nil {
return
}
tmpl, err := template.New("").Parse(debian_preseed)
if err != nil {
return
}
rootPassword, hashedRootPassword, err := randomPasswordHashed()
if err != nil {
return
}
preseed_arguments := preseedArgs{SSHKEY: sshKey, CRYPTED_PASSWORD: hashedRootPassword}
err = tmpl.Execute(&rendered_preseed, preseed_arguments)
if err != nil {
return
}
hash := md5.Sum(rendered_preseed.Bytes())
hash_hex := hex.EncodeToString(hash[:])
url, err := burnpaste.Write(burnpaste_endpoint, rendered_preseed.Bytes())
if err != nil {
return
}
tmpl, err = template.New("").Parse(debian_ipxescript)
if err != nil {
return
}
arguments := ipxescriptArgs{hostname, mirror, url, hash_hex}
err = tmpl.Execute(&return_script, arguments)
if err != nil {
return
}
response = IPXE{Script: return_script.String(), RootPassword: &rootPassword}
return
}