Implement an "OEM mode" installation medium

merge-requests/1/head
Matthias Klumpp 7 years ago
parent 757d3962fa
commit 83f76ff26e

@ -11,3 +11,6 @@ rm -f config/bootloaders/syslinux/live.cfg.in
rm -f config/bootloaders/isolinux/live.cfg.in
rm -f config/bootloaders/isolinux/grub-efi.cfg
rm -f build.log
rm -f config/hooks/normal/004-setup-oem.hook.chroot
rm -rf config/includes.chroot
rm -rf config/bootloaders/isolinux

@ -11,6 +11,13 @@ else
NORMAL=
fi
if [ -z "$FLAVOR" ]; then
FLAVOR="live"
echo "Using default flavor: $FLAVOR"
else
echo "Using flavor: $FLAVOR"
fi
# repository URL
PUREOS_REPO="http://repo.puri.sm/pureos"
@ -23,6 +30,8 @@ dist="green"
dist_version="3.0"
dist_reltag=""
VERSION_PRETTY=$dist_version
# live-build doesn't work if --parent-debian-distribution is unknown of
# debian-cd => we have to put a symlink so that it deals with Tanglu like jessie/sid
if [ ! -e "/usr/share/live/build/data/debian-cd/$dist" ]; then
@ -71,6 +80,9 @@ case "$arch" in
;;
esac
case "$FLAVOR" in
"live"|"LIVE")
FLAVOR=live
# create package config
cat > config/package-lists/desktop.list.chroot <<EOF
pureos-desktop
@ -79,12 +91,40 @@ calamares
grub-pc
EOF
# Configure bootloader
rm -f config/hooks/normal/004-setup-oem.hook.chroot
rm -rf config/includes.chroot
rm -rf config/bootloaders/isolinux
cp -r config/bootloaders/isolinux.live/ config/bootloaders/isolinux
cp -f config/bootloaders/live.cfg.in config/bootloaders/isolinux/
;;
"oem")
FLAVOR=oem
# create package config
cat > config/package-lists/desktop.list.chroot <<EOF
pureos-minimal
linux-image-$kernel_flavour
grub-pc
parted
python3-parted
EOF
rm -f config/hooks/normal/004-setup-oem.hook.chroot
cp config/oemhooks/004-setup-oem.hook.chroot config/hooks/normal/
rm -rf config/includes.chroot
cp -r config/includes.chroot.oem config/includes.chroot
rm -rf config/bootloaders/isolinux/
cp -r config/bootloaders/isolinux.oem config/bootloaders/isolinux
;;
esac
# Configure bootloader
sed -e s/@VERSION@/"$VERSION_PRETTY"/g config/bootloaders/splash.svg.in > config/bootloaders/splash.svg
mv -f config/bootloaders/splash.svg config/bootloaders/isolinux/
IMAGE_FILENAME=pureos-$dist_version-live
IMAGE_FILENAME=pureos-$dist_version-$FLAVOR
lb config noauto \
--distribution "$dist" \

@ -0,0 +1,7 @@
label hdt
menu label ^Hardware Detection Tool (HDT)
com32 hdt.c32
label memtest
menu label ^Memory Diagnostic Tool (memtest86+)
linux /live/memtest

@ -0,0 +1 @@
/usr/lib/syslinux/modules/bios/hdt.c32

@ -0,0 +1 @@
/usr/lib/ISOLINUX/isolinux.bin

@ -0,0 +1,4 @@
include menu.cfg
default vesamenu.c32
prompt 0
timeout 0

@ -0,0 +1 @@
/usr/lib/syslinux/modules/bios/ldlinux.c32

@ -0,0 +1 @@
/usr/lib/syslinux/modules/bios/libcom32.c32

@ -0,0 +1 @@
/usr/lib/syslinux/modules/bios/libutil.c32

@ -0,0 +1,12 @@
label live-@FLAVOUR@
menu label ^Install PureOS OEM and erase disk
menu default
linux @LINUX@
initrd @INITRD@
append @APPEND_LIVE@
label live-@FLAVOUR@-failsafe
menu label Install PureOS OEM and erase disk (^failsafe)
linux @LINUX@
initrd @INITRD@
append @APPEND_LIVE_FAILSAFE@

@ -0,0 +1,16 @@
menu hshift 0
menu width 82
menu title Boot menu
include stdmenu.cfg
include live.cfg
menu begin advanced
menu title Advanced options
include stdmenu.cfg
label mainmenu
menu label ^Back..
menu exit
include advanced.cfg
menu end
menu clear

@ -0,0 +1,15 @@
menu background splash.png
menu color title * #FFFFFFFF *
menu color border * #00000000 #00000000 none
menu color sel * #ffffffff #76a1d0ff *
menu color hotsel 1;7;37;40 #ffffffff #76a1d0ff *
menu color tabmsg * #ffffffff #00000000 *
menu color help 37;40 #ffdddd00 #00000000 none
menu vshift 12
menu rows 10
menu helpmsgrow 15
# The command line must be at least one line from the bottom.
menu cmdlinerow 16
menu timeoutrow 16
menu tabmsgrow 18
menu tabmsg Press ENTER to boot or TAB to edit a menu entry

@ -0,0 +1 @@
/usr/lib/syslinux/modules/bios/vesamenu.c32

@ -0,0 +1,75 @@
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
# don't put duplicate lines in the history. See bash(1) for more options
# don't overwrite GNU Midnight Commander's setting of `ignorespace'.
export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoredups
# ... or force ignoredups and ignorespace
export HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1400
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
#if [ -f ~/.bash_aliases ]; then
# . ~/.bash_aliases
#fi
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
eval "`dircolors -b`"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
#alias grep='grep --color=auto'
#alias fgrep='fgrep --color=auto'
#alias egrep='egrep --color=auto'
fi
# run PureOS OEM setup
sudo /var/lib/pureos-oem/install-pureos-oem.py

@ -0,0 +1,22 @@
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi

@ -0,0 +1,92 @@
## Options to set on the command line
#d-i debian-installer/locale string en_US
#d-i debian-installer/language boolean true
#d-i debian-installer/country boolean true
#d-i console-setup/ask_detect boolean false
d-i netcfg/enable boolean false
d-i clock-setup/utc-auto boolean true
d-i clock-setup/utc boolean true
#d-i time/zone string UTC
d-i clock-setup/ntp boolean true
d-i apt-setup/cdrom/set-first boolean true
d-i apt-setup/cdrom/set-double boolean false
d-i apt-setup/cdrom/set-next boolean false
d-i apt-setup/cdrom/set-failed boolean false
d-i apt-setup/use_mirror boolean false
d-i mirror/country string manual
d-i netcfg/get_hostname string librem
d-i netcfg/get_hostname seen false
d-i mirror/http/hostname string repo.puri.sm
d-i mirror/http/directory string /pureos
d-i mirror/http/proxy string
d-i pkgsel/install-language-support boolean false
d-i pkgsel/update-policy select none
d-i partman/default_filesystem string ext4
d-i partman-auto/disk string /dev/sda
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-auto-lvm/guided_size string max
d-i partman-auto/method string crypto
d-i partman-auto/choose_recipe select root-pureos
d-i partman-auto-lvm/new_vg_name string encrypted
d-i partman/early_command \
string sed -i.bak 's/-f $id\/skip_erase/-d $id/g' /lib/partman/lib/crypto-base.sh
d-i partman-auto/expert_recipe string \
root-pureos :: \
1000 2000 2100 ext4 \
$primary{ } \
method{ keep } \
use_filesystem{ } filesystem{ ext4 } \
label{ rescue } \
. \
800 800 800 ext4 \
$primary{ } $bootable{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ /boot } \
. \
2000 2000 2000 linux-swap \
$lvmok{ } lv_name{ swap } \
method{ swap } format{ } \
in_vg { encrypted } \
. \
1000 1000 1000000000 ext4 \
$lvmok{ } lv_name{ root } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ / } \
in_vg { encrypted } \
.
d-i partman-basicfilesystems/no_mount_point boolean false
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
user-setup-udeb passwd/root-login boolean false
user-setup-udeb user-setup/encrypt-home boolean true
d-i popularity-contest/participate boolean false
d-i hw-detect/load_firmware boolean false
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/choose_bootdev string /dev/sda
d-i finish-install/reboot_in_progress note
#grub-pc ucf/changeprompt string install the package maintainer's version
d-i preseed/late_command string cp /cdrom/purism/50_custom /target/etc/grub.d/50_custom;\
chmod a+x /target/etc/grub.d/50_custom;\
echo "GRUB_DISABLE_OS_PROBER=true" >> /target/etc/default/grub;\
in-target sed -e '/boot/s/^#*/#/' -i /etc/fstab;\
in-target update-grub;

@ -0,0 +1,12 @@
set default=0
set timeout=1
insmod tga
set color_normal=light-gray/black
set color_highlight=white/light-blue
menuentry "Initial Setup" {
set isofile="/pureos.iso"
linux /vmlinuz video=vesa:ywrap,mtrr vga=788 quiet iso-scan/filename=${isofile} auto=true file=/hd-media/di-preseed.cfg
initrd /initrd.gz
}

@ -0,0 +1,168 @@
#!/usr/bin/env python3
import os
import math
from glob import glob
from logging import getLogger
import logging
import shutil
import parted
def check_call(args):
import sys
from subprocess import check_call
return check_call(args, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
class _ConsoleHandler(logging.StreamHandler):
def __init__(self):
super().__init__()
self.setFormatter(
logging.Formatter('{levelname} - {message}', style='{')
)
class LibremDiskDevice(object):
"""
A simple model of a block storage device that wraps up some examples of
pyparted capabilities.
"""
def __init__(self, path):
"""
Initialize the ExampleDevice object.
"""
self.path = path
self.logger = getLogger(__name__)
@property
def partition_names(self):
"""
@return: A list of partition device names on the block device.
@rtype: str
"""
names = glob('{}[0-9]*'.format(self.path))
self.logger.debug('has partitions %s', names)
return names
def _new_partition(self, device, disk, start, length, set_boot=False):
geometry = parted.Geometry(device=device, start=start,
length=length)
self.logger.debug('created %s', geometry)
filesystem = parted.FileSystem(type='ext4', geometry=geometry)
self.logger.debug('created %s', filesystem)
partition = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL,
fs=filesystem, geometry=geometry)
self.logger.debug('created %s', partition)
disk.addPartition(partition=partition,
constraint=device.optimalAlignedConstraint)
if set_boot:
partition.setFlag(parted.PARTITION_BOOT)
return partition
def partition(self):
"""
Create a partition table on the block device.
"""
self.logger.info('Creating partitions')
device = parted.getDevice(self.path)
self.logger.debug('created %s', device)
disk = parted.freshDisk(device, 'msdos')
self.logger.debug('created %s', disk)
# create the rescue disk partition
partition_size = round((math.pow(1024.0, parted._exponent['gb']) * 2) / (device.sectorSize)) # 2 GB
self._new_partition(device, disk, 1, partition_size, True)
disk.commit()
# for some reason, parted doesn't format this on its own, so we do it
check_call(['mkfs.ext4', '/dev/sda1'])
#check_call(['mkfs.ext4', '/dev/sda2'])
check_call(['e2label', '/dev/sda1', 'rescue'])
def wipe_dev(self, dev_path):
"""
Wipe a device (partition or otherwise) of meta-data, be it file system,
LVM, etc.
@param dev_path: Device path of the partition to be wiped.
@type dev_path: str
"""
self.logger.debug('wiping %s', dev_path)
with open(dev_path, 'wb') as p:
p.write(bytearray(1024))
def wipe(self):
"""
Wipe the block device of meta-data, be it file system, LVM, etc.
This is not intended to be secure, but rather to ensure that
auto-discovery tools don't recognize anything here.
"""
self.logger.info('Wiping partitions and other meta-data')
for partition in self.partition_names:
self.wipe_dev(partition)
self.wipe_dev(self.path)
def pureos_oem_setup():
OEM_DATA_PATH = '/var/lib/pureos-oem/'
logger = getLogger(__name__)
# create the new partition and format it
libremhdd = LibremDiskDevice(disk_path)
libremhdd.wipe()
libremhdd.partition()
# mount the setup disk
logger.info('Mounting setup disk...')
target = os.path.join(OEM_DATA_PATH, 'target')
try:
os.makedirs(target)
except:
pass
check_call(['mount', '/dev/sda1', target])
# copy PureOS image files and d-i
logger.info('Copying PureOS install files...')
shutil.copy(os.path.join(OEM_DATA_PATH, 'pureos.iso'), target)
shutil.copy(os.path.join(OEM_DATA_PATH, 'initrd.gz'), target)
shutil.copy(os.path.join(OEM_DATA_PATH, 'vmlinuz'), target)
shutil.copy(os.path.join(OEM_DATA_PATH, 'di-preseed.cfg'), target)
# set up GRUB
logger.info('Creating GRUB configuration...')
boot_dir = os.path.join(target, 'boot')
grub_dir = os.path.join(boot_dir, 'grub')
try:
os.makedirs(grub_dir)
except:
pass
shutil.copy(os.path.join(OEM_DATA_PATH, 'grub', 'grub.cfg'), grub_dir)
shutil.copy(os.path.join(OEM_DATA_PATH, 'grub', 'loopback.cfg'), grub_dir)
logger.info('Installing GRUB...')
check_call(['grub-install', '/dev/sda', '--boot-directory=%s' % (boot_dir)])
check_call(['umount', target])
logger.info('Done.')
shutdown = input('Shutdown now? [Y/n]')
if not shutdown.strip() or shutdown.lower() == 'y':
check_call(['systemctl', 'poweroff'])
if __name__ == '__main__':
disk_path = '/dev/sda'
# Set up a logger for nice visibility.
logger = getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(_ConsoleHandler())
pureos_oem_setup()

@ -0,0 +1,16 @@
#!/bin/sh
set -e
OEM_DIR=/var/lib/pureos-oem/
mkdir -p $OEM_DIR
cd $OEM_DIR
apt install -y ca-certificates
# d-i components
wget http://repo.pureos.net/pureos/dists/green/main/installer-amd64/20170525pureos3/images/hd-media/gtk/initrd.gz
wget http://repo.pureos.net/pureos/dists/green/main/installer-amd64/20170525pureos3/images/hd-media/gtk/vmlinuz
# PureOS image
wget --progress=dot:giga https://downloads.puri.sm/snapshots/2017-05-31/pureos-3.0-live-amd64.hybrid.iso -O pureos.iso
Loading…
Cancel
Save