Initial commit

This commit is contained in:
Jan Schär 2022-07-15 11:59:26 +02:00
commit 295a111cec
89 changed files with 2897 additions and 0 deletions

21
config/class/10-base-classes Executable file
View file

@ -0,0 +1,21 @@
#! /bin/bash
# do only execute if this is called on the client being installed. Do not use during fai-diskimage
if [ X$FAI_ACTION = Xinstall -a $do_init_tasks -eq 0 ]; then
exit 0
fi
# Echo architecture and OS name in uppercase. Do NOT remove these two lines.
uname -s | tr '[:lower:]' '[:upper:]'
command -v dpkg >&/dev/null && dpkg --print-architecture | tr a-z A-Z
# determin if we are a DHCP client or not
# count the : chars in the argument of ip=
n="${ip//[^:]}"
if [[ $ip =~ ^(on|any|dhcp)$ ]]; then
echo DHCPC
elif [ ${#n} -lt 6 ]; then
echo DHCPC
fi
exit 0

36
config/class/20-hwdetect.sh Executable file
View file

@ -0,0 +1,36 @@
#! /bin/bash
# (c) Thomas Lange, 2002-2013, lange@informatik.uni-koeln.de
# NOTE: Files named *.sh will be evaluated, but their output ignored.
[ $do_init_tasks -eq 1 ] || return 0 # Do only execute when doing install
echo 0 > /proc/sys/kernel/printk
#kernelmodules=
# here, you can load modules depending on the kernel version
case $(uname -r) in
2.6*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;;
[3456]*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;;
esac
for mod in $kernelmodules; do
[ X$verbose = X1 ] && echo Loading kernel module $mod
modprobe -a $mod 1>/dev/null 2>&1
done
# show the basic information about the network interface
ip -br li show up|egrep -v ^lo; ip -br a show up|egrep -v ^lo
echo $printk > /proc/sys/kernel/printk
odisklist=$disklist
set_disk_info # recalculate list of available disks
if [ "$disklist" != "$odisklist" ]; then
echo New disklist: $disklist
echo disklist=\"$disklist\" >> $LOGDIR/additional.var
fi
save_dmesg # save new boot messages (from loading modules)

32
config/class/41-warning.sh Executable file
View file

@ -0,0 +1,32 @@
#! /bin/bash
if [ X$FAI_ACTION = Xinstall -o X$FAI_ACTION = X ]; then
:
else
return 0
fi
if [ X$action = Xdirinstall ]; then
return 0
fi
grep -q INSTALL $LOGDIR/FAI_CLASSES || return 0
[ "$flag_menu" ] || return 0
out=$(tty)
red=$(mktemp)
echo 'screen_color = (CYAN,RED,ON)' > $red
DIALOGRC=$red dialog --colors --clear --aspect 6 --title "FAI - Fully Automatic Installation" --trim \
--msgbox "\n\n If you continue, \n all your data on the disk \n \n|\Zr\Z1 WILL BE DESTROYED \Z0\Zn|\n\n" 0 0 1>$out
# stop on any error, or if ESC was hit
if [ $? -ne 0 ]; then
task_error 999
fi
rm $red
unset red
# MENU DISABLED
unset flag_menu
FAI_ACTION=install

8
config/class/50-host-classes Executable file
View file

@ -0,0 +1,8 @@
#! /bin/bash
# assign classes to hosts based on their hostname
# do not use this if a menu will be presented
[ "$flag_menu" ] && exit 0
echo "FAIBASE DEBIAN XORG GNOME PARTICIPANT CONTESTANT"

10
config/class/55-classes Executable file
View file

@ -0,0 +1,10 @@
#! /bin/bash
[ "$cmdlineclasses" ] || exit 0
# define the classes given on the cmdline (using -c)
# Note: In the FAI example config, this script has very low priority, but for
# me it make more sense to make it higher priority than the host classes.
echo $cmdlineclasses
exit 0

11
config/class/60-misc Executable file
View file

@ -0,0 +1,11 @@
#! /bin/bash
ifclass -o CENTOS SLC && exit 0
ifclass -o GRUB_PC GRUB_EFI && exit 0
if [ -d /sys/firmware/efi ]; then
echo GRUB_EFI
elif ifclass -o I386 AMD64 ; then
echo GRUB_PC
fi

14
config/class/85-efi-classes Executable file
View file

@ -0,0 +1,14 @@
#! /bin/bash
# define classes for disk_config in an EFI enironment
if [ ! -d /sys/firmware/efi ] || ifclass GRUB_PC; then
exit 0
fi
for c in LVM FAIBASE; do
if ifclass $c; then
echo ${c}_EFI
break
fi
done

View file

@ -0,0 +1 @@
PARTICIPANT_USER_NAME=contestant

26
config/class/DEBIAN.var Normal file
View file

@ -0,0 +1,26 @@
release=bullseye
apt_cdn=http://deb.debian.org
security_cdn=http://security.debian.org
# since bullseye Debian changed the suite name for security
if [ $release = buster ]; then
secsuite=buster/updates
else
secsuite=$release-security
fi
CONSOLEFONT=
KEYMAP=us-latin1
# MODULESLIST contains modules that will be loaded by the new system,
# not during installation these modules will be written to /etc/modules
# If you need a module during installation, add it to $kernelmodules
# in 20-hwdetect.sh.
MODULESLIST="usbhid psmouse"
# if you have enough RAM (>2GB) you may want to enable this line. It
# also puts /var/cache into a ramdisk.
#FAI_RAMDISKS="$target/var/lib/dpkg $target/var/cache"
# if you want to use the faiserver as APT proxy
APTPROXY=http://10.0.0.9:3142

24
config/class/FAIBASE.var Normal file
View file

@ -0,0 +1,24 @@
# default values for installation. You can override them in your *.var files
# disallow installation of packages from unsigned repositories
FAI_ALLOW_UNSIGNED=0
# Set UTC=yes if your system clock is set to UTC (GMT), and UTC=no if not.
UTC=yes
TIMEZONE=Europe/Zurich
# the hash of the root password for the new installed linux system
ROOTPW=''
# errors in tasks greater than this value will cause the installation to stop
STOP_ON_ERROR=700
# set parameter for install_packages(8)
MAXPACKAGES=800
PARTICIPANT_USER_NAME=soi
PARTICIPANT_USER_PW='$y$j9T$h5VhMd4KkdmbxdZD1gO0N/$1hvwZgO8pQw13Xd6jaNXbtkbqVOC4W/ia/KXOcCGYvB'
if [ $FAI_ACTION = "install" ]; then
LOGUSER=fai
fi

View file

@ -0,0 +1,3 @@
SUPER_USER_NAME=superstofl
SUPER_USER_DISPLAYNAME="Admin"
SUPER_USER_PW=''

10
config/debconf/DEBIAN Normal file
View file

@ -0,0 +1,10 @@
exim4-config exim4/dc_eximconfig_configtype select local delivery only; not on a network
locales locales/default_environment_locale select en_US.UTF-8
locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8
keyboard-configuration keyboard-configuration/xkb-keymap select
keyboard-configuration keyboard-configuration/model select Generic 105-key PC
keyboard-configuration keyboard-configuration/modelcode string pc105
keyboard-configuration keyboard-configuration/layoutcode string ch
keyboard-configuration keyboard-configuration/layout select Switzerland
keyboard-configuration keyboard-configuration/variant select Switzerland
keyboard-configuration keyboard-configuration/optionscode string

View file

@ -0,0 +1,2 @@
locales locales/default_environment_locale select en_US.UTF-8
locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8, de_CH.UTF-8 UTF-8, fr_CH.UTF-8 UTF-8, it_CH.UTF-8 UTF-8

View file

@ -0,0 +1,9 @@
# example of new config file for setup-storage
#
# <type> <mountpoint> <size> <fs type> <mount options> <misc options>
disk_config disk1 disklabel:msdos bootable:1 fstabkey:uuid
primary / 2G-50G ext4 rw,noatime,errors=remount-ro
logical swap 200-10G swap sw
logical /home 100- ext4 rw,noatime,nosuid,nodev createopts="-L home -m 1" tuneopts="-c 0 -i 0"

View file

@ -0,0 +1,10 @@
# example of new config file for setup-storage
#
# <type> <mountpoint> <size> <fs type> <mount options> <misc options>
disk_config disk1 disklabel:gpt bootable:1 fstabkey:uuid
primary /boot/efi 512M vfat rw
primary / 2G-50G ext4 rw,noatime,errors=remount-ro
primary swap 200-10G swap sw
primary /home 100- ext4 rw,noatime,nosuid,nodev createopts="-L home -m 1" tuneopts="-c 0 -i 0"

15
config/disk_config/LVM Normal file
View file

@ -0,0 +1,15 @@
# <type> <mountpoint> <size> <fs type> <mount options> <misc options>
# entire disk with LVM, separate /home
disk_config disk1 fstabkey:uuid align-at:1M
primary /boot 200 ext2 rw,noatime
primary - 4G- - -
disk_config lvm
vg vg1 disk1.2
vg1-root / 3G-50G ext4 noatime,rw
vg1-swap swap 200-4G swap sw
vg1-home /home 600- ext4 noatime,nosuid,nodev,rw

View file

@ -0,0 +1,16 @@
# <type> <mountpoint> <size> <fs type> <mount options> <misc options>
# entire disk with LVM, separate /home
disk_config disk1 disklabel:gpt fstabkey:uuid align-at:1M
primary /boot/efi 512M vfat rw
primary /boot 200 ext2 rw,noatime
primary - 4G- - -
disk_config lvm
vg vg1 disk1.3
vg1-root / 3G-50G ext4 noatime,rw
vg1-swap swap 200-4G swap sw
vg1-home /home 600- ext4 noatime,nosuid,nodev,rw

View file

@ -0,0 +1,5 @@
DPkg {
Options {
"--force-confdef";
}
};

View file

@ -0,0 +1,3 @@
deb {%apt_cdn%}/debian {%release%} main contrib non-free
deb {%security_cdn%}/debian-security {%secsuite%} main contrib non-free
deb {%apt_cdn%}/debian {%release%}-updates main contrib non-free

View file

45
config/hooks/debconf.IMAGE Executable file
View file

@ -0,0 +1,45 @@
#! /bin/bash
# hook for installing a file system image (tar file)
# this works for Ubuntu 14.04
#
# Copyright (C) 2015 Thomas Lange, lange@informatik.uni-koeln.de
# I use this tar command to create the image of an already running and configured machine
# tar -cf /tmp/IMAGE.tar --exclude /tmp/\* --exclude /run/\* --exclude /proc/\* --exclude /sys/\* --exclude /dev/\* /
# add --xattrs --selinux --acls if needed (for CentOS 7)
# Then copy this image to /srv/fai/config/basefiles/IMAGE.tar and make sure your client belongs to the class IMAGE
skiptask extrbase debconf repository updatebase instsoft
skiptask configure # do not run the usual configure scripts
# we assume, that the new host will get its hostname and IP via DHCP
# remove old hostname
fgrep -v 127.0.1.1 $target/etc/hosts >> /tmp/fai/hosts
mv /tmp/fai/hosts $target/etc/hosts
rm $target/etc/hostname
#install grub
mount -t proc proc $FAI_ROOT/proc
mount -t sysfs sysfs $FAI_ROOT/sys
mount --bind /dev $FAI_ROOT/dev
if [ -f $target/etc/debian_version ]; then
$ROOTCMD grub-install $BOOT_DEVICE
$ROOTCMD update-grub
fi
if [ -f $target/etc/centos-release ]; then
rm $target/etc/grub2/device.map
$FAI/scripts/CENTOS/40-install-grub
$FAI/scripts/CENTOS/30-mkinitrd
$ROOTCMD fixfiles onboot # this fixes the SELinux security contexts during the first boot
fi
# things that may be adjusted:
#
# MAC address ?? (not needed for Ubuntu, it uses iftab(5)
# /etc/hosts may contain the IP and name of the original host
# /etc/hostname (for Ubuntu just remove it)
# /var/lib/NetworkManager/dhclient-eth0.conf?

25
config/hooks/instsoft.DEBIAN Executable file
View file

@ -0,0 +1,25 @@
#! /bin/bash
# if package locales will be installed, then install it early, before
# other packages
if [ $FAI_ACTION != "install" -a $FAI_ACTION != "dirinstall" ]; then
exit 0
fi
fcopy -Bi /etc/apt/apt.conf.d/force_confdef
ainsl -a /etc/ucf.conf "^conf_force_conffold=YES"
# in case the locales are already included inside the base file (Ubuntu)
if [ -f $target/usr/sbin/locale-gen ]; then
exit
fi
# if we want to install locales, install them now
install_packages -l 2>/dev/null | egrep -q ' locales|locales '
if [ $? -eq 0 ]; then
if [ X$verbose = X1 ]; then
$ROOTCMD apt-get -y install locales
else
$ROOTCMD apt-get -y install locales > /dev/null
fi
fi

222
config/hooks/savelog.LAST.sh Executable file
View file

@ -0,0 +1,222 @@
#! /bin/bash
# parse all log files for error messages
# print errors and warnings found to error.log
# WARNING: This will only work with english error messages!
errfile=$LOGDIR/error.log
# Define grep patterns. Do not start or end with an empty line!
globalerrorpatterns="error
fail
warn
bad
bad
no space
Couldn't stat
Cannot access
conflict
is bigger than the limit
did not exist
non existent
not found
couldn't
can't
E: Sorry, broken packages
^E:
operator expected
ambiguous redirect
No previous regular expression
No such
Device or resource busy
unknown option
[a-z]\+\.log:E:
No candidate version found
segfault
Couldn't find any package whose name or description matched
cannot create
The following packages have unmet dependencies"
globalignorepatterns="[a-z]\+\.log:#
Error: Driver 'pcspkr' is already registered, aborting
: bytes packets errors dropped
:+ error=0
:+ trap error=
task_error_func=
STOP_ON_ERROR=
courier-webadmin
plugins-bad
Enabling conf localized-error-pages
ibwebadmin
kernel-patch-badram
kolab-webadmin
kolabadmin
gstreamer.\+-plugins-really-bad
liberrors.so
liberrors-samba
libsamba-errors
gsambad
libad
libtest-nowarnings-perl
libtest-warn-perl
libclass-errorhandler-perl
zope-ploneerrorreporting
libroxen-errormessage
liberror-perl
perl-Error
libgpg-error-dev
libgpg-error0
Opts:.\+errors=remount
[RT]X packets:
WARNING: unexpected IO-APIC
warned about = ( )
daemon.warn
kern.warn
rw,errors=
Expect some cache
no error
failmsg
RPC call returned error 101
deverror.out
(floppy), sector 0
mount version older than kernel
Can't locate module
Warning only .\+MB will be used.
hostname: Host name lookup failure
I can't tell the difference.
warning, not much extra random data, consider using the -rand option
confC._FILE
Warning: 3 database(s) sources
were not found, (but were created)
removing exim
The home dir you specified already exists.
No Rule for /usr/lib/ispell/default.hash.
/usr/sbin/update-fonts-.\+: warning: absolute path
hostname: Unknown server error
EXT2-fs warning: checktime reached
RPC: sendmsg returned error 101
can't print them to stdout. Define these classes
warning: downgrading
suppress emacs errors
echo Error:
Can't open dependencies file
documents in /usr/doc are no longer supported
if you have both a SCSI and an IDE CD-ROM
Warning: /proc/ide/hd?/settings interface is obsolete, and will be removed soon
Monitoring disabled
Error: only one processor found.
Error Recovery Strategy:
sector 0 does not have an
syslogin_perform_logout: logout() returned an error
grub is not in an XFS filesystem.
grub-install: line 374:
grub-probe: error: Cannot open \`/boot/grub/device.map'
is harmless
not updating .\+ font directory data.
register_serial(): autoconfig failed
Fontconfig error: Cannot load default config file
asking for cache data failed
However, I can not read the target:
Warning: The partition table looks like it was made
task_error=0
task_local_error=0
^info: Trying to set
warning: /usr/lib/X11/fonts
can't read /etc/udev/rules.d/z25_persistent-net.rules
/cow': No such file or directory
Dummy start-stop-daemon called
X: bytes packets errors
ACPI Error
ACPI Warning
AE_NOT_FOUND
conflicts with ACPI region
cannot stat \`/etc/modprobe.d/\*.conf'
cdrom: open failed.
libgpg-error
process \`kudzu' used the deprecated sysctl system call
PM: Resume from disk failed
JBD: barrier-based sync failed
aufs: module is from the staging directory, the quality is unknown
warning: linuxlogo stop runlevel arguments (none) do not match
insserv: warning: script .\+ missing LSB tags and overrides
live-premount.\+ If this fails
cannot read table of mounted file systems
error: no alternatives for
ERST: Error Record Serialization Table (ERST) support is initialized
ERST: Table is not found
HEST: Table not found
failed to stat /dev/pts
Failed to connect to socket /var/run/dbus/system_bus_socket
fail to add MMCONFIG information
can't initialize iptables table
can't initialize ip6tables table
Authentication warning overridden
41-warning.sh
PCCT header not found
Download is performed unsandboxed as root as file
update-alternatives: warning: skip creation of
loop: module verification failed: signature
Warning: apt-key output should not be parsed
WARNING: Failed to connect to lvmetad. Falling back to device scanning
Warning: The home dir /var/lib/usbmux you specified
diff: /var/lib/apparmor/profiles/.apparmor.md5sums: No such file or directory
error reporting disabled
Enabling Firmware First mode for corrected errors
errors: 0
0 errors
Memory Error Correction:
Memory Controller 0 - Channel . Error
IIO RAS/Control Status/Global Errors
RAS: Correctable Errors collector initialized
__stack_chk_fail
grub.cfg.new: Directory nonexistent
can't derive routing for PCI INT A
failed to load isci/isci_firmware.bin
Direct firmware load for isci/isci_firmware.bin failed with error
Loading user firmware failed, using default values
stunnel4 you specified can't be accessed: No such file or directory
install-docs --verbose --check file_name' may give more details about the above errors
cannot open '/etc/ssl/certs/java/cacerts' for reading: No such file or directory
can't claim BAR
disabling ASPM
data block query control method not found
subprocess.py.\+RuntimeWarning: line buffering
Resource conflict.\+ found
update-rc.d: warning: start and stop actions are no longer supported"
# add pattern on some conditions
if [ -n $FAI_ALLOW_UNSIGNED ] ; then
globalignorepatterns="$globalignorepatterns
WARNING: untrusted versions
WARNING: The following packages cannot be authenticated
Ignoring these trust violations"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Here you can define your own patterns. Put one pattern in a line,
# do not create empty lines.
myerrorpatterns="X_X-X_XX"
myignorepatterns="X_X-X_XX"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# The main routine
errorpatterns="$globalerrorpatterns
$myerrorpatterns"
ignorepatterns="$globalignorepatterns
$myignorepatterns"
cd $LOGDIR || exit 3
if [ -s $errfile ]; then
echo "Errorfile already exists. Aborting." >&2
exit
fi
grep -i "$errorpatterns" *.log | grep -vi "$ignorepatterns" > $errfile
if [ X$verbose = X1 ]; then
egrep -v '^software.log:' $errfile > $LOGDIR/tempfile
mv $LOGDIR/tempfile $errfile
fi
if [ -s $errfile ]; then
echo "ERRORS found in log files. See $errfile" >&2
else
echo "Congratulations! No errors found in log files."
fi

7
config/hooks/setup.DEFAULT.sh Executable file
View file

@ -0,0 +1,7 @@
#! /bin/bash
# use short hostname instead of FQDN
export HOSTNAME=${HOSTNAME%%.*}
if [ $do_init_tasks -eq 1 ]; then
echo $HOSTNAME > /proc/sys/kernel/hostname
fi

16
config/hooks/updatebase.DEBIAN Executable file
View file

@ -0,0 +1,16 @@
#! /bin/bash
if [ -n "$APTPROXY" ]; then
echo "Acquire::http::Proxy \"$APTPROXY\";" > $target/etc/apt/apt.conf.d/02proxy
else
rm -f $target/etc/apt/apt.conf.d/02proxy
fi
echo force-unsafe-io > $target/etc/dpkg/dpkg.cfg.d/unsafe-io
fcopy -iSM /etc/apt/sources.list
# you may want to add i386 arch to amd64 hosts
# if ifclass AMD64; then
# $ROOTCMD dpkg --add-architecture i386
# fi

View file

@ -0,0 +1,4 @@
#! /bin/bash
cp -RT $FAI/simplefiles/PARTICIPANT/usr/share/keyrings $target/usr/share/keyrings
cp -RT $FAI/simplefiles/PARTICIPANT/etc/apt/sources.list.d $target/etc/apt/sources.list.d

View file

@ -0,0 +1,7 @@
PACKAGES install-norec
# For fai softupdate
nfs-common netcat fai-client
# For importing client certificate
libnss3-tools
# For screen recording
ffmpeg

View file

@ -0,0 +1,54 @@
PACKAGES install-norec
apt-transport-https # is only needed for stretch
debconf-utils
file
less
linuxlogo
rsync
openssh-client openssh-server
time
procinfo
nullmailer
eject
locales
console-setup kbd
pciutils usbutils
systemd-timesyncd
#unattended-upgrades
PACKAGES install NONFREE
# you may want these non-free kernel drivers
firmware-bnx2 firmware-bnx2x firmware-realtek
firmware-linux-nonfree
# a list of firmware for wifi/wireless
atmel-firmware firmware-atheros firmware-brcm80211
firmware-iwlwifi firmware-libertas firmware-ralink firmware-zd1211
firmware-brcm80211 firmware-ti-connectivity
firmware-netronome firmware-netxen firmware-realtek
firmware-cavium
# firmware-ipw2x00 # needs a debconf question
PACKAGES install I386
linux-image-686-pae
memtest86+
PACKAGES install CHROOT
linux-image-686-pae-
linux-image-amd64-
PACKAGES install AMD64
linux-image-amd64
memtest86+
PACKAGES install ARM64
grub-efi-arm64
linux-image-arm64
PACKAGES install GRUB_PC
grub-pc
PACKAGES install GRUB_EFI
grub-efi
PACKAGES install LVM
lvm2

Binary file not shown.

View file

@ -0,0 +1,8 @@
PACKAGES install-norec
firefox-esr
#thunderbird
menu gdm3
gnome-core
gnome-screensaver gnome-system-monitor gnome-system-tools
network-manager-gnome

View file

@ -0,0 +1,15 @@
PACKAGES install
# firmware
firmware-linux-nonfree
firmware-iwlwifi firmware-brcm80211 firmware-realtek
# shell utilities
netcat htop
# software for participants
chromium-l10n
codeblocks emacs geany gedit joe kate kdevelop nano vim vim-gtk3
gcc g++ gdb ddd valgrind python3 pypy
evince gnome-terminal konsole byobu
# from third-party repositories
atom sublime-text code
# requested by particants (gnome-tweaks can be used e.g. to change the function of Caps Lock key)
gnome-tweaks fonts-firacode

View file

@ -0,0 +1,37 @@
PACKAGES install-norec
# the list of standard packages, without any libs and a few packages removed
apt-listchanges
bash-completion
bind9-host
dbus
dnsutils
doc-debian
file
gettext-base
groff-base
hdparm
less
locales
lsof
man-db
manpages
mime-support
ncurses-term
netcat-traditional
openssh-client
pciutils
perl
reportbug
telnet
traceroute
ucf
xz-utils
PACKAGES install-norec STRETCH BUSTER
python
python-minimal
PACKAGES install-norec BULLSEYE
python3
python3-minimal

View file

@ -0,0 +1,2 @@
PACKAGES install-norec
sudo

View file

@ -0,0 +1,12 @@
PACKAGES install-norec DEBIAN
xorg xserver-xorg-video-all xserver-xorg-input-all
fonts-freefont-ttf
xscreensaver
xscreensaver-gl
xterm
desktop-base
PACKAGES install UBUNTU
ubuntu-server-
ubuntu-standard
ubuntu-desktop

View file

@ -0,0 +1,30 @@
#! /bin/bash
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
cp -RT $FAI/simplefiles/CONTESTANT $target
$ROOTCMD dconf update
# Enable firewall
$ROOTCMD systemctl enable nftables.service
# Disable Bluetooth
$ROOTCMD systemctl disable bluetooth.service
# Disable sleep
$ROOTCMD systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
sed -i 's|"homepage": ".*"|"homepage": "https://finals.soi.ch/"|' $target/etc/chromium/master_preferences
# Disable panels in gnome-control-center
DISABLE_DESKTOP="$ROOTCMD dpkg-statoverride --force-statoverride-add --update --add root root 640"
$DISABLE_DESKTOP /usr/share/applications/gnome-bluetooth-panel.desktop
$DISABLE_DESKTOP /usr/share/applications/gnome-online-accounts-panel.desktop
$DISABLE_DESKTOP /usr/share/applications/gnome-sharing-panel.desktop
# Auto login
sed -i 's/# AutomaticLoginEnable = true/AutomaticLoginEnable = true/g' $target/etc/gdm3/daemon.conf
sed -i 's/# AutomaticLogin = user1/AutomaticLogin = contestant/g' $target/etc/gdm3/daemon.conf
exit $error

12
config/scripts/DEBIAN/10-rootpw Executable file
View file

@ -0,0 +1,12 @@
#! /bin/bash
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
# set root password
if [ -n "$ROOTPW" ]; then
$ROOTCMD chpasswd --encrypted <<< "root:${ROOTPW}"
else
$ROOTCMD usermod -L root
fi
exit $error

View file

@ -0,0 +1,22 @@
#!/bin/bash
#
# Capabilities get lost when creating the fai base.tar.xz image.
# Restore them here.
#
set -e
if [ ! -x $target/sbin/setcap ] ; then
exit 0
fi
for FILE in /bin/ping /bin/ping6 /usr/bin/fping /usr/bin/fping6; do
if [ -x $target/$FILE -a ! -h $target/$FILE ] ; then
if $ROOTCMD /sbin/setcap cap_net_raw+ep $FILE; then
echo "Setcap worked! $FILE is not suid!"
fi
fi
done
if [ -x $target/usr/bin/systemd-detect-virt ] ; then
$ROOTCMD /sbin/setcap cap_dac_override,cap_sys_ptrace+ep /usr/bin/systemd-detect-virt
fi

View file

@ -0,0 +1,118 @@
#! /bin/bash
netplan_yaml() {
# network configuration using ubuntu's netplan.io
local IFNAME="$1"
local METHOD="$2"
echo "Generating netplan configuration for $IFNAME ($METHOD)" >&2
echo "# generated by FAI"
echo "network:"
echo " version: 2"
echo " renderer: $RENDERER"
case "$RENDERER" in
networkd)
echo " ethernets:"
echo " $IFNAME:"
case "$METHOD" in
dhcp)
echo " dhcp4: true"
;;
static)
echo " addresses: [$CIDR]"
echo " gateway4: $GATEWAYS_1"
echo " nameservers:"
echo " search: [$DOMAIN]"
echo " addresses: [${DNSSRVS// /, }]"
;;
esac
esac
}
iface_stanza() {
# classic network configuration using /etc/network/interfaces
local IFNAME="$1"
local METHOD="$2"
echo "Generating interface configuration for $IFNAME ($METHOD)" >&2
echo "# generated by FAI"
echo "auto $IFNAME"
echo "iface $IFNAME inet $METHOD"
case "$METHOD" in
static)
echo " address $CIDR"
echo " gateway $GATEWAYS"
;;
esac
}
newnicnames() {
# determine predictable network names only for stretch and above
local name
[ $do_init_tasks -eq 0 ] && return
[ -z "$NIC1" ] && return
fields="ID_NET_NAME_FROM_DATABASE ID_NET_NAME_ONBOARD ID_NET_NAME_SLOT ID_NET_NAME_PATH"
for field in $fields; do
name=$(udevadm info /sys/class/net/$NIC1 | sed -rn "s/^E: $field=(.+)/\1/p")
if [[ $name ]]; then
NIC1=$name
return
fi
done
# try to get altname net dev
name=$(ip link show $NIC1 | awk '/altname / { print $2 }')
if [[ $name ]]; then
NIC1=$name
return
else
echo "$0: error: could not find systemd predictable network name. Using $NIC1."
fi
}
if [ -z "$NIC1" ]; then
echo "WARNING: \$NIC1 is not defined. Cannot add ethernet to /etc/network/interfaces."
fi
CIDR=$(ip --br ad sh $NIC1|awk '{print $3}')
newnicnames
case "$FAI_ACTION" in
install|dirinstall)
ifclass DHCPC && METHOD=dhcp || METHOD=static
ifclass XORG && RENDERER=NetworkManager || RENDERER=networkd
if [ -d $target/etc/netplan ]; then
# Ubuntu >= 17.10 with netplan.io
if [ -n "$NIC1" ]; then
netplan_yaml $NIC1 $METHOD > $target/etc/netplan/01-${NIC1}.yaml
fi
elif [ -d $target/etc/network/interfaces.d ]; then
# ifupdown >= 0.7.41 (Debian >= 8, Ubuntu >= 14.04)
iface_stanza lo loopback > $target/etc/network/interfaces.d/lo
if [ -n "$NIC1" -a ! -f $target/etc/NetworkManager/NetworkManager.conf ]; then
iface_stanza $NIC1 $METHOD > $target/etc/network/interfaces.d/$NIC1
fi
else
(
iface_stanza lo loopback
iface_stanza $NIC1 $METHOD
) > $target/etc/network/interfaces
fi
if ! ifclass DHCPC ; then
[ -n "$NETWORK" ] && echo "localnet $NETWORK" > $target/etc/networks
if [ ! -L $target/etc/resolv.conf -a -e /etc/resolv.conf ]; then
cp -p /etc/resolv.conf $target/etc
fi
fi
;;
esac
# here fcopy is mostly used, when installing a client for running in a
# different subnet than during the installation
fcopy -iM /etc/resolv.conf
fcopy -iM /etc/network/interfaces /etc/networks
exit $error

51
config/scripts/DEBIAN/40-misc Executable file
View file

@ -0,0 +1,51 @@
#! /bin/bash
# (c) Thomas Lange, 2001-2016, lange@debian.org
# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
# a list of modules which are loaded at boot time
for module in $MODULESLIST; do
ainsl -a /etc/modules "^$module$"
done
fcopy -Mv /etc/hostname || echo $HOSTNAME > $target/etc/hostname
ainsl -a /etc/mailname ${HOSTNAME}
if [ ! -e $target/etc/adjtime ]; then
printf "0.0 0 0.0\n0\nUTC\n" > $target/etc/adjtime
fi
if [ "$UTC" = "yes" ]; then
sed -i -e 's:^LOCAL$:UTC:' $target/etc/adjtime
else
sed -i -e 's:^UTC$:LOCAL:' $target/etc/adjtime
fi
# enable linuxlogo
if [ -f $target/etc/inittab ]; then
sed -i -e 's#/sbin/getty 38400#/sbin/getty -f /etc/issue.linuxlogo 38400#' ${target}/etc/inittab
elif [ -f $target/lib/systemd/system/getty@.service ]; then
sed -i -e 's#sbin/agetty --noclear#sbin/agetty -f /etc/issue.linuxlogo --noclear#' $target/lib/systemd/system/getty@.service
fi
# make sure a machine-id exists
if [ ! -f $target/etc/machine-id ]; then
> $target/etc/machine-id
fi
# recreate machine-id if the file is empty
if [ X"$(stat -c '%s' $target/etc/machine-id 2>/dev/null)" = X0 -a -f $target/bin/systemd-machine-id-setup ]; then
$ROOTCMD systemd-machine-id-setup
fi
ln -fs /proc/mounts $target/etc/mtab
rm -f $target/etc/dpkg/dpkg.cfg.d/fai $target/etc/dpkg/dpkg.cfg.d/unsafe-io
if [ -d /etc/fai ]; then
if ! fcopy -Mv /etc/fai/fai.conf; then
ainsl -a /etc/fai/fai.conf "FAI_CONFIG_SRC=$FAI_CONFIG_SRC"
fi
fi
fcopy -iv /etc/rc.local
exit $error

38
config/scripts/FAIBASE/10-misc Executable file
View file

@ -0,0 +1,38 @@
#! /bin/bash
# (c) Thomas Lange, 2001-2012, lange@debian.org
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
echo $TIMEZONE > $target/etc/timezone
if [ -L $target/etc/localtime ]; then
ln -sf /usr/share/zoneinfo/${TIMEZONE} $target/etc/localtime
else
cp -f /usr/share/zoneinfo/${TIMEZONE} $target/etc/localtime
fi
if [ -f $target/etc/hosts.orig ]; then
mv $target/etc/hosts.orig $target/etc/hosts
fi
if [ -n "$IPADDR" ]; then
# ifclass DHCPC ||
ainsl -s /etc/hosts "$IPADDR $HOSTNAME.$DOMAIN $HOSTNAME"
else
ifclass DHCPC && ainsl -s /etc/hosts "127.0.0.1 $HOSTNAME"
fi
fcopy -iM /etc/hosts /etc/motd
# make /root accessible only by root
chmod -c 0700 $target/root
chown -c root:root $target/root
# copy default dotfiles for root account
fcopy -ir /root
# use tmpfs for /tmp if not defined in disk_config
if ! grep -Pq '\s/tmp\s' $target/etc/fstab; then
ainsl /etc/fstab "tmpfs /tmp tmpfs nodev,nosuid,size=50%,mode=1777 0 0"
fi
chmod -c 1777 ${target}/tmp
chown -c 0:0 ${target}/tmp
exit $error

View file

@ -0,0 +1,25 @@
#! /bin/bash
# (c) Thomas Lange, 2006,2009, lange@debian.org
# create entries for removable media in fstab and directories in /media
cdromlist() {
[ -f /proc/sys/dev/cdrom/info ] || return
devs=$(grep 'drive name:' /proc/sys/dev/cdrom/info | cut -d ":" -f 2)
for d in $devs; do
echo $d
done
}
fstabline () {
line=$(printf "%-15s %-15s %-7s %-15s %-7s %s\n" "$1" "$2" "$3" "$4" "$5" "$6")
ainsl /etc/fstab "$line"
}
i=0
for cdrom in $(cdromlist | tac); do
[ $i -eq 0 ] && ln -sfn cdrom0 $target/media/cdrom
mkdir -p $target/media/cdrom$i
fstabline /dev/$cdrom /media/cdrom$i udf,iso9660 ro,user,noauto 0 0
i=$((i + 1))
done

View file

@ -0,0 +1,68 @@
#! /bin/bash
# support for GRUB version 2
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
# This script assumes that the disk has a GPT partition table and
# that the extended system partition (ESP) is mounted on /boot/efi.
# When building a disk image, we don't change the NVRAM to point at
# the boot image we made available, because the disk image is likely
# not installed on the current system. As a result, we force
# installation into the removable media paths as well as the standard
# debian path.
set -a
# do not set up grub during dirinstall
if [ "$FAI_ACTION" = "dirinstall" ] ; then
exit 0
fi
# during softupdate use this file
[ -r $LOGDIR/disk_var.sh ] && . $LOGDIR/disk_var.sh
if [ -z "$BOOT_DEVICE" ]; then
exit 189
fi
# disable os-prober because of #802717
ainsl /etc/default/grub 'GRUB_DISABLE_OS_PROBER=true'
# skip the rest, if not an initial installation
if [ $FAI_ACTION != "install" ]; then
$ROOTCMD update-grub
exit $error
fi
GROOT=$($ROOTCMD grub-probe -tdrive -d $BOOT_DEVICE)
# handle /boot in lvm-on-md
_bdev=$(readlink -f $BOOT_DEVICE)
if [ "${_bdev%%-*}" = "/dev/dm" ]; then
BOOT_DEVICE=$( lvs --noheadings -o devices $BOOT_DEVICE | sed -e 's/^*\([^(]*\)(.*$/\1/' )
fi
# Check if RAID is used for the boot device
if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then
raiddev=${BOOT_DEVICE#/dev/}
# install grub on all members of RAID
for device in $(LC_ALL=C perl -ne 'if(/^'$raiddev'\s.+raid\d+\s(.+)/){ $_=$1; s/\d+\[\d+\]//g; print }' /proc/mdstat); do
echo Install grub on /dev/$device
$ROOTCMD grub-install --no-floppy --force-extra-removable "/dev/$device"
done
elif [[ $BOOT_DEVICE =~ '/dev/loop' ]]; then
# do not update vmram when using a loop device
$ROOTCMD grub-install --no-floppy --force-extra-removable --modules=part_gpt --no-nvram $BOOT_DEVICE
if [ $? -eq 0 ]; then
echo "Grub installed on hostdisk $BOOT_DEVICE"
fi
else
$ROOTCMD grub-install --no-floppy --modules=part_gpt "$GROOT"
if [ $? -eq 0 ]; then
echo "Grub installed on $BOOT_DEVICE = $GROOT"
fi
fi
$ROOTCMD update-grub
exit $error

84
config/scripts/GRUB_PC/10-setup Executable file
View file

@ -0,0 +1,84 @@
#! /bin/bash
# support for GRUB version 2
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
set -a
# do not set up grub during dirinstall
if [ "$FAI_ACTION" = "dirinstall" ] ; then
exit 0
fi
# during softupdate use this file
[ -r $LOGDIR/disk_var.sh ] && . $LOGDIR/disk_var.sh
if [ -z "$BOOT_DEVICE" ]; then
exit 189
fi
# disable os-prober because of #802717
ainsl /etc/default/grub 'GRUB_DISABLE_OS_PROBER=true'
# skip the rest, if not an initial installation
if [ $FAI_ACTION != "install" ]; then
$ROOTCMD update-grub
exit $error
fi
get_stable_devname() {
local _DEV="$1"
local i
declare -a _RES
# prefer SCSI over ATA over WWN over path
# do not use by-path
for i in $($ROOTCMD udevadm info -r --query=symlink "$_DEV"); do
if [[ "$i" =~ /by-id/scsi ]]; then
_RES[10]="$i"
elif [[ "$i" =~ /by-id/ata ]]; then
_RES[20]="$i"
elif [[ "$i" =~ /by-id/wwn ]]; then
_RES[99]="$i"
fi
done
echo "${_RES[@]::1}"
}
# handle /boot in lvm-on-md
_bdev=$(readlink -f $BOOT_DEVICE)
if [ "${_bdev%%-*}" = "/dev/dm" ]; then
BOOT_DEVICE=$( lvs --noheadings -o devices $BOOT_DEVICE | sed -e 's/^*\([^(]*\)(.*$/\1/' )
fi
# Check if RAID is used for the boot device
if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then
raiddev=${BOOT_DEVICE#/dev/}
# install grub on all members of RAID
for device in $(LC_ALL=C perl -ne 'if(/^'$raiddev'\s.+raid\d+\s(.+)/){ $_=$1; s/\d+\[\d+\]//g; s/(nvme.+?)p/$1/g; print }' /proc/mdstat); do
pdevice=$(get_stable_devname /dev/$device)
if [ -z "$pdevice" ]; then
# if we cannot find a persistent name (for e.g. in a VM) use old name
pdevice="/dev/$device"
fi
mbrdevices+="$pdevice, "
echo Installing grub on /dev/$device = $pdevice
$ROOTCMD grub-install --no-floppy "/dev/$device"
done
# remove last ,
mbrdevices=${mbrdevices%, }
else
mbrdevices=$(get_stable_devname $BOOT_DEVICE)
if [ -z "$mbrdevices" ]; then
# if we cannot find a persistent name (for e.g. in a VM) use old name
mbrdevices=$BOOT_DEVICE
fi
echo "Installing grub on $BOOT_DEVICE = $mbrdevices"
$ROOTCMD grub-install --no-floppy "$mbrdevices"
fi
echo "grub-pc grub-pc/install_devices multiselect $mbrdevices" | $ROOTCMD debconf-set-selections
$ROOTCMD dpkg-reconfigure grub-pc
exit $error

103
config/scripts/LAST/50-misc Executable file
View file

@ -0,0 +1,103 @@
#! /bin/bash
# copyright Thomas Lange 2001-2016, lange@debian.org
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
if [ "$FAI_ACTION" = "dirinstall" -o $do_init_tasks -eq 0 ] ; then
:
else
# check if mdadm has been forgotten
if grep -q active /proc/mdstat 2>/dev/null; then
if [ ! -d $target/etc/mdadm ]; then
echo ERROR: Found Software RAID, but the mdadm package was not installed
error=1
fi
fi
usedm=$(dmsetup ls 2>/dev/null | egrep -v '^live-rw|^live-base|^No devices found' | wc -l)
if [ $usedm -ne 0 ]; then
if [ ! -d $target/etc/lvm ]; then
echo ERROR: Found lvm devices, but the lvm2 package was not installed
error=1
fi
fi
fi
# remove backup files from cfengine, but only if cfengine is installed
if [ -x /usr/sbin/cfagent ] || [ -x $target/usr/sbin/cfagent ] ; then
dirs="root etc var"
for path in $dirs; do
find $target/$path -maxdepth 20 -name \*.cfedited -o -name \*.cfsaved | xargs -r rm
done
fi
[ "$FAI_DEBMIRROR" ] &&
ainsl /etc/fstab "#$FAI_DEBMIRROR $MNTPOINT nfs ro 0 0"
# set bios clock
if [ $do_init_tasks -eq 1 ] ; then
case "$UTC" in
no|"") hwopt="--localtime" ;;
yes) hwopt="--utc" ;;
esac
hwclock $hwopt --systohc || true
fi
# Make sure everything is configured properly
if ifclass DEBIAN ; then
$ROOTCMD apt-get -f install -y
fi
if [ $FAI_ACTION = "install" ]; then
lskernels=$(echo $target/boot/vmlinu*)
if [ ! -f ${lskernels%% *} ]; then
echo "ERROR: No kernel was installed. Have a look at shell.log" >&2
error=1
fi
fi
# copy sources.list
fcopy -iSM /etc/apt/sources.list
setrel() {
# if release is not set, try to determine it
if [ -n "$release" ]; then
return
fi
if [ ! -f $target/etc/os-release ]; then
return
fi
dists="jessie stretch buster bullseye bookworm trixie focal bionic xenial trusty"
for d in $dists; do
if grep -iq $d $target/etc/os-release; then
release=$d
break
fi
done
}
# if installation was done from CD, replace useless sources.list
setrel
if [ -f $target/etc/apt/sources.list -a -n "$release" ]; then
grep -q 'file generated by fai-cd' $target/etc/apt/sources.list && cat <<EOF > $target/etc/apt/sources.list
deb $apt_cdn/debian $release main contrib non-free
deb $security_cdn/debian-security ${secsuite} main contrib non-free
#deb [trusted=yes] http://fai-project.org/download $release koeln
EOF
# if the package fai-server was installed, enable the project's repository
if dpkg-query --admindir=$target/var/lib/dpkg -W fai-server >/dev/null 2>&1; then
sed -i -e '/fai-project.org/s/^#//' $target/etc/apt/sources.list
fi
fi
# for ARM architecture, we may need the kernel and initrd to boot or flash the device
if ifclass ARM64; then
cp -pv $target/boot/vmlinuz* $target/boot/initrd* $FAI_RUNDIR
fi
exit $error

View file

@ -0,0 +1,56 @@
#! /bin/bash
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
cp -RT $FAI/simplefiles/PARTICIPANT $target
$ROOTCMD dconf update
# Uncomment this to reinstall extensions
# (disabled by default to speed up softupdate):
# rm -rf $target/etc/skel/.vscode
# VS Code extensions
if [ ! -d $target/etc/skel/.vscode ]; then
# To avoid running VS Code as root, run it as nobody instead.
mkdir $target/etc/skel/.vscode
chown nobody:nogroup $target/etc/skel/.vscode
shopt -s nullglob
for ext in $FAI/downloads/*.vsix; do
# We can't access the config space inside ROOTCMD, so we copy the file to the target.
cp "$ext" $target/tmp/ext.vsix
$ROOTCMD runuser -u nobody -- code --user-data-dir=/tmp/vsc.tmp \
--extensions-dir=/etc/skel/.vscode/extensions \
--install-extension=/tmp/ext.vsix
done
chown -R root:root $target/etc/skel/.vscode
rm -rf $target/tmp/vsc.tmp $target/tmp/ext.vsix
fi
# Install soi header
tar --overwrite -xf $FAI/downloads/soi-header.tar.gz -C $target/usr/local/include --strip-components=2 soi-header/include/
# Install codeblocks template
$target/bin/unzip -o $FAI/downloads/soi_template_codeblocks_ubuntu_RzdvSho.zip -d $target/usr/share/codeblocks/templates/wizard/
if ! grep -q '_T("soi")' $target/usr/share/codeblocks/templates/wizard/config.script ; then
sed -i 's|// project wizards|RegisterWizard(wizProject, _T("soi"), _T("A SOI task"), _T("Console"));|' $target/usr/share/codeblocks/templates/wizard/config.script
fi
# add super user account
if [ -n "$SUPER_USER_NAME" ]; then
if ! $ROOTCMD getent passwd $SUPER_USER_NAME ; then
$ROOTCMD adduser --disabled-login --gecos "$SUPER_USER_DISPLAYNAME" $SUPER_USER_NAME
$ROOTCMD usermod -p "$SUPER_USER_PW" $SUPER_USER_NAME
$ROOTCMD adduser $SUPER_USER_NAME sudo
fi
fi
# add participant account
if [ -n "$PARTICIPANT_USER_NAME" ]; then
if ! $ROOTCMD getent passwd $PARTICIPANT_USER_NAME ; then
$ROOTCMD adduser --disabled-login --gecos "$PARTICIPANT_USER_NAME" $PARTICIPANT_USER_NAME
$ROOTCMD usermod -p "$PARTICIPANT_USER_PW" $PARTICIPANT_USER_NAME
fi
fi
exit $error

View file

@ -0,0 +1,8 @@
#! /bin/bash
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
# Remove APT proxy
rm -f $target/etc/apt/apt.conf.d/02proxy
exit $error

41
config/setup-bern.sh Executable file
View file

@ -0,0 +1,41 @@
#! /bin/bash
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
FAI=/var/lib/bernconfig
target=/
apt-get install libnss3-tools gnome-tweaks fonts-firacode
rsync --archive \
--exclude /etc/apt \
--exclude /usr/share/keyrings \
--exclude /etc/ssh \
$FAI/simplefiles/PARTICIPANT/ $target
rsync --archive \
--exclude /etc/systemd/timesyncd.conf.d \
--exclude /etc/hosts \
--exclude /etc/nftables.conf \
--exclude /root \
$FAI/simplefiles/CONTESTANT/ $target
sed -i 's|firefox-esr|firefox_firefox|' $target/etc/dconf/db/local.d/00-favorite-apps
$ROOTCMD dconf update
# Install soi header
tar --overwrite -xf $FAI/downloads/soi-header.tar.gz -C $target/usr/local/include --strip-components=2 soi-header/include/
# Disable panels in gnome-control-center
DISABLE_DESKTOP="$ROOTCMD dpkg-statoverride --force-statoverride-add --update --add root root 640"
$DISABLE_DESKTOP /usr/share/applications/gnome-bluetooth-panel.desktop
$DISABLE_DESKTOP /usr/share/applications/gnome-online-accounts-panel.desktop
$DISABLE_DESKTOP /usr/share/applications/gnome-sharing-panel.desktop
# Auto login
sed -i 's/# AutomaticLoginEnable = true/AutomaticLoginEnable = true/g' $target/etc/gdm3/custom.conf
sed -i 's/# AutomaticLogin = user1/AutomaticLogin = contestant/g' $target/etc/gdm3/custom.conf
exit $error

View file

@ -0,0 +1,3 @@
# Disable blank screen
[org/gnome/desktop/session]
idle-delay=uint32 0

View file

@ -0,0 +1,3 @@
# Disable lock on blank screen
[org/gnome/desktop/screensaver]
lock-enabled = false

View file

@ -0,0 +1,4 @@
# Disable suspend when inactive
[org/gnome/settings-daemon/plugins/power]
sleep-inactive-ac-type = 'nothing'
sleep-inactive-battery-type = 'nothing'

View file

@ -0,0 +1,3 @@
# This prevents "Updates available" notifications
[org/gnome/software]
allow-updates = false

View file

@ -0,0 +1,2 @@
[org/gnome/shell]
enabled-extensions = ['contest-lock@soi.ch', 'user-indicator@soi.ch']

View file

@ -0,0 +1,3 @@
# Disable locking the screen
[org/gnome/desktop/lockdown]
disable-lock-screen=true

View file

@ -0,0 +1,23 @@
{
"policies": {
"OverrideFirstRunPage": "",
"NoDefaultBookmarks": true,
"DisableProfileImport": true,
"Preferences": {
"datareporting.policy.dataSubmissionPolicyBypassNotification": true,
"security.default_personal_cert": "Select Automatically"
},
"Homepage": {
"URL": "https://finals.soi.ch/",
"StartPage": "homepage"
},
"DisplayBookmarksToolbar": true,
"Bookmarks": [
{
"Title": "Grader",
"URL": "https://finals.soi.ch/",
"Placement": "toolbar"
}
]
}
}

View file

@ -0,0 +1,33 @@
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.8 finals.soi.ch
10.0.0.9 contestserver
10.0.0.10 contestant10
10.0.0.11 contestant11
10.0.0.12 contestant12
10.0.0.13 contestant13
10.0.0.14 contestant14
10.0.0.15 contestant15
10.0.0.16 contestant16
10.0.0.17 contestant17
10.0.0.18 contestant18
10.0.0.19 contestant19
10.0.0.20 contestant20
10.0.0.21 contestant21
10.0.0.22 contestant22
10.0.0.23 contestant23
10.0.0.24 contestant24
10.0.0.25 contestant25
10.0.0.26 contestant26
10.0.0.27 contestant27
10.0.0.28 contestant28
10.0.0.40 test40

View file

@ -0,0 +1,45 @@
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
ct state invalid drop
ct state { established, related } accept
# Accept loopback
iif lo accept
# Accept ICMP
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# Accept incoming connections to these ports
tcp dport { ssh } accept
reject
}
chain forward {
type filter hook forward priority 0;
reject
}
chain output {
type filter hook output priority 0;
ct state invalid drop
ct state { established, related } accept
# Accept loopback
oif lo accept
# Accept outgoing connections to these addresses
ip daddr { 10.0.0.1-10.0.0.9 } accept
# Accept any connections by root user
#meta skuid root accept
reject
}
}

View file

@ -0,0 +1,11 @@
# Show a root password prompt for these actions:
# - change network settings
# - hibernate
# - change package download proxy
# - mount removable storage, perform other disk operations
[Disallow actions]
Identity=unix-user:*
Action=org.freedesktop.ModemManager1.*;org.freedesktop.NetworkManager.*;org.freedesktop.login1.hibernate;org.freedesktop.packagekit.system-network-proxy-configure;org.freedesktop.udisks2.*
ResultActive=auth_admin
ResultInactive=auth_admin
ResultAny=auth_admin

View file

@ -0,0 +1,3 @@
[Time]
NTP=finals.soi.ch
FallbackNTP=10.0.0.9

View file

@ -0,0 +1,49 @@
#!/bin/bash
# This tool installs the client certificate in Firefox and Chromium.
username="$1"
userhome="/home/$username"
certificate="$userhome/.config/clientcert.p12"
runuser -u "$username" -- mkdir -p "$userhome/.config"
mv "$userhome/clientcert.p12" "$certificate"
chown "$username:$username" "$certificate"
# Delete all Firefox data
rm -rf "$userhome/.mozilla/"
# Create an empty profile
runuser -u "$username" -- mkdir -p "$userhome/.mozilla/firefox/main"
# Tell Firefox to user this profile
cat <<EOF >"$userhome/.mozilla/firefox/profiles.ini"
[Profile0]
Name=main
IsRelative=1
Path=main
[General]
StartWithLastProfile=1
Version=2
[Install3B6073811A6ABF12]
Default=main
Locked=1
EOF
chown "$username:$username" "$userhome/.mozilla/firefox/profiles.ini"
# Create a certificate database
runuser -u "$username" -- certutil -d "sql:$userhome/.mozilla/firefox/main/" -N --empty-password
# Import the client certificate
runuser -u "$username" -- pk12util -d "sql:$userhome/.mozilla/firefox/main/" -i "$certificate" -K "" -W ""
# Do the same for the NSS shared certificate database, used by Chromium
rm -rf "$userhome/.pki/"
runuser -u "$username" -- mkdir -p "$userhome/.pki/nssdb"
runuser -u "$username" -- certutil -d "sql:$userhome/.pki/nssdb/" -N --empty-password
runuser -u "$username" -- pk12util -d "sql:$userhome/.pki/nssdb/" -i "$certificate" -K "" -W ""

View file

@ -0,0 +1,10 @@
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
<DT><H3 PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Bar</H3>
<DL><p>
<DT><A HREF="https://finals.soi.ch/" ICON="data:image/png;base64,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">Grader</A>
</DL><p>
</DL><p>

View file

@ -0,0 +1,424 @@
// Portions of this file are taken from GNOME Shell and adapted.
// Because of that, this gnome extension is distributed under
// the terms of the GNU General Public License, version 2.
const {
AccountsService, Atk, Clutter, Gio,
GLib, Graphene, Meta, Shell, St,
} = imports.gi;
const Background = imports.ui.background;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
// half of the time for which a frame is displayed
const HALF_FRAME_TIME_MS = 8;
const BLUR_BRIGHTNESS = 0.55;
const BLUR_SIGMA = 60;
const POINTER_HIDE_TIMEOUT = 10 * GLib.USEC_PER_SEC;
let actor;
let lockDialog;
let labelCountdown;
let labelTitle;
let labelMessage;
let labelUser;
const bgManagers = [];
let backgroundGroup;
let cursorTracker;
let motionId = 0;
let lastMotionTime = 0;
let pointerHidden = false;
let pointerHideId = 0;
let user;
let grab;
let countdownTimeoutId = 0;
let configFile;
let configMonitor;
let config;
let startTime;
let isExtensionEnabled = false;
let isActive = false;
let isShellReady = false;
let isActiveChanging = false;
function extLog (msg) {
log(`[contest-lock] ${msg}`)
}
function extLogError (msg) {
printerr(`[contest-lock] Error: ${msg}`);
}
function loadConfig () {
configFile.load_contents_async(null, (obj, res) => {
// If there is a poblem with the config file, log an error and keep
// using the old config.
let newConfig;
try {
const [ok, bytes] = configFile.load_contents_finish(res);
// TextDecoder is used in upstream gnome-shell, but not yet
// supported in current Debian.
const contentStr = imports.byteArray.toString(bytes);
//const contentStr = new TextDecoder().decode(bytes);
newConfig = JSON.parse(contentStr);
} catch (err) {
logError(err, '[contest-lock] config file');
return;
}
if (!(typeof newConfig === 'object' && newConfig != null)) {
extLogError('config file: invalid format');
return;
}
if (typeof newConfig.title !== 'string') {
extLogError('config file: "title" must be a string');
return;
}
if (typeof newConfig.message !== 'string') {
extLogError('config file: "message" must be a string');
return;
}
if (
typeof newConfig.startTime !== 'string' ||
!/^\d{4,}-\d\d-\d\dT\d\d:\d\d:\d\d\+\d\d:\d\d$/.test(newConfig.startTime)
) {
extLogError('config file: "startTime" must be a string with format 0000-00-00T00:00:00+00:00');
return;
}
extLog('Loaded new config.')
config = newConfig;
startTime = (new Date(newConfig.startTime)).getTime();
updateConfig();
syncActive();
});
}
function syncActive () {
if (isActiveChanging) return;
let beforeStart = false;
if (startTime != null) {
const now = new Date();
const timeToStart = startTime - now.getTime() - HALF_FRAME_TIME_MS;
beforeStart = timeToStart > 0;
}
// ignore disable event when active
if (beforeStart && isShellReady && (isExtensionEnabled || isActive)) {
activate();
} else {
deactivate();
}
}
function updateConfig () {
if (labelTitle != null) {
labelTitle.text = config.title;
}
if (labelMessage != null) {
labelMessage.text = config.message;
}
}
function updateUser () {
if (labelUser != null) {
const realName = user.get_real_name();
if (realName != null) labelUser.text = realName;
}
}
function updateCountdown () {
countdownTimeoutId = 0;
const now = new Date();
const nowTime = now.getTime() + HALF_FRAME_TIME_MS;
const timeToStart = startTime - nowTime;
const beforeStart = timeToStart > 0;
if (!beforeStart) {
deactivate();
return GLib.SOURCE_REMOVE;
}
const allSecondsToStart = Math.floor(timeToStart / 1000);
const secondsToStart = allSecondsToStart % 60
const allMinutesToStart = Math.floor(allSecondsToStart / 60);
const minutesToStart = allMinutesToStart % 60;
const hoursToStart = Math.floor(allMinutesToStart / 60);
let hoursString = '';
if (hoursToStart !== 0) hoursString = `${hoursToStart}`;
labelCountdown.text = hoursString +
minutesToStart.toString().padStart(2, '0') + '' +
secondsToStart.toString().padStart(2, '0');
const nextUpdateTime = 1000 - nowTime % 1000
countdownTimeoutId = GLib.timeout_add(
GLib.PRIORITY_HIGH,
nextUpdateTime,
updateCountdown
);
GLib.Source.set_name_by_id(countdownTimeoutId, '[contest-lock] updateCountdown');
return GLib.SOURCE_REMOVE;
}
function updateBackgrounds () {
if (!isActive) return;
while (bgManagers.length) bgManagers.pop().destroy();
backgroundGroup.destroy_all_children();
for (let monitorIndex = 0; monitorIndex < Main.layoutManager.monitors.length; monitorIndex++) {
const monitor = Main.layoutManager.monitors[monitorIndex];
const widget = new St.Widget({
style_class: 'screen-shield-background',
x: monitor.x,
y: monitor.y,
width: monitor.width,
height: monitor.height,
effect: new Shell.BlurEffect({
name: 'blur',
brightness: BLUR_BRIGHTNESS,
sigma: BLUR_SIGMA,
}),
});
const bgManager = new Background.BackgroundManager({
container: widget,
monitorIndex,
controlPosition: false,
});
bgManagers.push(bgManager);
backgroundGroup.add_child(widget);
}
}
function pointerHideTimer () {
if (pointerHideId !== 0) {
GLib.source_remove(pointerHideId);
pointerHideId = 0;
}
if (!isActive) return GLib.SOURCE_REMOVE;
const timeToHide = lastMotionTime + POINTER_HIDE_TIMEOUT - GLib.get_monotonic_time();
if (timeToHide <= 0) {
cursorTracker.set_pointer_visible(false);
pointerHidden = true;
return GLib.SOURCE_REMOVE;
}
pointerHideId = GLib.timeout_add(
GLib.PRIORITY_HIGH,
timeToHide / 1000 + 20,
pointerHideTimer
);
GLib.Source.set_name_by_id(pointerHideId, '[contest-lock] pointerHide');
return GLib.SOURCE_REMOVE;
}
function activate () {
if (isActive) return;
isActiveChanging = true;
isActive = true;
grab = Main.pushModal(Main.uiGroup, { actionMode: Shell.ActionMode.LOCK_SCREEN });
if (typeof grab === 'boolean') { // gnome 38
if (!grab) {
grab = Main.pushModal(Main.uiGroup, {
options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
actionMode: Shell.ActionMode.LOCK_SCREEN
});
}
if (!grab) {
extLogError('Failed to activate: Could not obtain keyboard grab.');
return;
}
grab = Main.uiGroup;
} else if ((grab.get_seat_state() & Clutter.GrabState.KEYBOARD) === 0) {
Main.popModal(grab);
grab = null;
extLogError('Failed to activate: Could not obtain keyboard grab.');
return;
}
actor.show();
Main.sessionMode.pushMode('unlock-dialog');
backgroundGroup = new Clutter.Actor();
motionId = global.stage.connect('captured-event', (stage, event) => {
if (event.type() === Clutter.EventType.MOTION) {
lastMotionTime = GLib.get_monotonic_time();
if (pointerHidden) {
cursorTracker.set_pointer_visible(true);
pointerHidden = false;
pointerHideTimer();
}
}
return Clutter.EVENT_PROPAGATE;
});
cursorTracker.set_pointer_visible(false);
pointerHidden = true;
labelCountdown = new St.Label({
style_class: 'contest-lock-countdown',
x_align: Clutter.ActorAlign.CENTER,
});
labelTitle = new St.Label({
style_class: 'contest-lock-title',
x_align: Clutter.ActorAlign.CENTER,
});
labelMessage = new St.Label({
style_class: 'contest-lock-message',
x_align: Clutter.ActorAlign.CENTER,
});
labelUser = new St.Label({
style_class: 'contest-lock-user',
x_align: Clutter.ActorAlign.CENTER,
});
const stack = new St.BoxLayout({
style_class: 'contest-lock-stack',
vertical: true,
x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
})
stack.add_child(labelUser);
stack.add_child(labelCountdown);
stack.add_child(labelTitle);
stack.add_child(labelMessage);
const mainBox = new St.BoxLayout();
mainBox.add_constraint(new Layout.MonitorConstraint({ primary: true }));
mainBox.add_child(stack);
lockDialog = new St.Widget({
name: 'contestLockDialog',
accessible_role: Atk.Role.WINDOW,
visible: false,
reactive: true,
can_focus: true,
x_expand: true,
y_expand: true,
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
});
lockDialog.add_child(backgroundGroup);
lockDialog.add_child(mainBox);
updateConfig();
updateUser();
updateCountdown();
updateBackgrounds();
// countdown may have just expired before we called updateCountdown
if (!isActive) return;
actor.add_child(lockDialog);
lockDialog.show();
extLog('Activated.')
isActiveChanging = false;
}
function deactivate () {
if (!isActive) return;
isActiveChanging = true;
isActive = false;
if (Main.sessionMode.currentMode === 'unlock-dialog') {
Main.sessionMode.popMode('unlock-dialog');
}
Main.popModal(grab);
grab = null;
if (countdownTimeoutId !== 0) {
GLib.source_remove(countdownTimeoutId);
countdownTimeoutId = 0;
}
actor.hide();
labelCountdown = null;
labelTitle = null;
labelMessage = null;
labelUser = null;
while (bgManagers.length) bgManagers.pop().destroy();
lockDialog.destroy();
lockDialog = null;
if (motionId) {
global.stage.disconnect(motionId);
motionId = 0;
}
cursorTracker.set_pointer_visible(true);
extLog('Deactivated.');
isActiveChanging = false;
}
function init (extension) {
actor = Main.layoutManager.screenShieldGroup;
const userName = GLib.get_user_name();
user = AccountsService.UserManager.get_default().get_user(userName);
if (!user) return;
user.connect('notify::is-loaded', updateUser);
user.connect('changed', updateUser);
updateUser();
Main.layoutManager.connect('monitors-changed', updateBackgrounds);
cursorTracker = Meta.CursorTracker.get_for_display(global.display);
if (!Main.layoutManager._startingUp) {
isShellReady = true;
} else {
Main.layoutManager.connect('startup-complete', () => {
isShellReady = true;
syncActive();
});
}
// TODO: When we drop compatibility with gnome <42, remove this code,
// rename the stylesheet back to stylesheet.css (so that it is loaded
// by the extension system) and add a session-modes property which
// includes unlock-dialog to metadata.json.
const theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
const stylesheetFile = extension.dir.get_child('stylesheet-always.css');
theme.load_stylesheet(stylesheetFile);
// TODO: When we drop compatibility with gnome <42, remove this code.
// gnome 38 has a bug that causes extensions to break when running
// `dconf update` while the screen is locked.
Main.extensionManager.reloadExtension = function () {};
configFile = Gio.File.new_for_path('/etc/contest-lock.json');
configMonitor = configFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
configMonitor.set_rate_limit(1000);
configMonitor.connect('changed', loadConfig);
loadConfig();
}
function enable () {
isExtensionEnabled = true;
syncActive();
}
function disable () {
isExtensionEnabled = false;
syncActive();
}

View file

@ -0,0 +1,8 @@
{
"extension-id": "contest-lock",
"uuid": "contest-lock@soi.ch",
"name": "Contest lock screen",
"description": "A custom lock screen for contests.",
"shell-version": [ "3.38", "42" ],
"url": ""
}

View file

@ -0,0 +1,24 @@
.contest-lock-stack {
color: white;
text-align: center;
spacing: 24px;
}
.contest-lock-countdown {
font-size: 64pt;
font-weight: 300;
font-feature-settings: "tnum"; /* tabular figures */
}
.contest-lock-title {
font-size: 16pt;
}
.contest-lock-user {
font-size: 20pt;
}
.contest-lock-message {
padding-top: 24px;
font-size: 16pt;
}

View file

@ -0,0 +1,39 @@
const { St, Clutter, GLib, Gio, AccountsService } = imports.gi;
const Main = imports.ui.main;
let panelBin;
let userLabel;
let user;
function updateUser () {
const realName = user.get_real_name();
if (realName != null) userLabel.text = realName;
}
function init () {
panelBin = new St.Bin({
style_class: 'panel-bin',
});
userLabel = new St.Label({
text: 'No user',
y_align: Clutter.ActorAlign.CENTER,
});
panelBin.set_child(userLabel);
const userName = GLib.get_user_name();
user = AccountsService.UserManager.get_default().get_user(userName);
if (!user) return;
user.connect('notify::is-loaded', updateUser);
user.connect('changed', updateUser);
updateUser();
}
function enable () {
Main.panel._rightBox.insert_child_at_index(panelBin, 0);
}
function disable () {
Main.panel._rightBox.remove_child(panelBin);
}

View file

@ -0,0 +1,8 @@
{
"extension-id": "user-indicator",
"uuid": "user-indicator@soi.ch",
"name": "User indicator",
"description": "Shows the user's real name in the top bar.",
"shell-version": [ "3.38", "42" ],
"url": ""
}

View file

@ -0,0 +1,3 @@
.panel-bin {
padding-left: 12px;
padding-right: 12px; }

View file

@ -0,0 +1 @@
deb [arch=amd64 signed-by=/usr/share/keyrings/atom-archive-keyring.gpg] http://packagecloud.io/AtomEditor/atom/any/ any main

View file

@ -0,0 +1 @@
deb [arch=amd64 signed-by=/usr/share/keyrings/sublimehq-archive-keyring.gpg] http://download.sublimetext.com/ apt/stable/

View file

@ -0,0 +1 @@
deb [arch=amd64,arm64,armhf signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] http://packages.microsoft.com/repos/code stable main

View file

@ -0,0 +1,5 @@
[org/gnome/desktop/background]
picture-uri = 'file:///usr/local/share/backgrounds/wallpaper-soi.svg'
picture-options = 'scaled'
primary-color = '#e6e6e6'
secondary-color = '#555555'

View file

@ -0,0 +1,2 @@
[org/gnome/shell]
favorite-apps = ['firefox-esr.desktop', 'gnome-terminal.desktop', 'nautilus.desktop']

View file

@ -0,0 +1,5 @@
# Configure the default keyboard layouts shown in the switcher
# According to Wikipedia, the Italian-speaking part of Switzerland also uses the ch+fr layout.
# The first option is the default.
[org/gnome/desktop/input-sources]
sources = [('xkb', 'ch'), ('xkb', 'ch+fr'), ('xkb', 'us')]

View file

@ -0,0 +1,2 @@
user-db:user
system-db:local

View file

@ -0,0 +1,2 @@
PasswordAuthentication no
AllowUsers root

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" viewBox="-20 -20 153.6 86.4" width="1920" height="1080" version="1.1" id="svg22" sodipodi:docname="wallpaper.svg" inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata id="metadata28">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title>Swiss Olympiad in Informatics</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs id="defs26"/>
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1669" inkscape:window-height="913" id="namedview24" showgrid="false" inkscape:zoom="0.472" inkscape:cx="811.36486" inkscape:cy="502.72794" inkscape:window-x="67" inkscape:window-y="27" inkscape:window-maximized="0" inkscape:current-layer="svg22"/>
<title id="title2">Swiss Olympiad in Informatics</title>
<rect style="fill:#e6e6e6;fill-opacity:1;stroke:#f9fdff;stroke-width:0.60472441;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect837" width="160" height="97.627121" x="-23.050846" y="-24.955931"/>
<circle r="18.903814" id="circle4" cx="57.553818" cy="24.70454" style="fill:none;stroke:#303030;stroke-width:3.43705702"/>
<path d="M 68.019104,24.704538 57.553815,14.239249 75.801426,3.0788495 M 47.088526,24.704538 H 68.019104 L 57.553815,35.169826 47.088526,24.704538 37.798573,43.321151" id="path6" inkscape:connector-curvature="0" style="fill:none;stroke:#1eadf5;stroke-width:2.74964571"/>
<g id="g20" style="fill:#1862ff" transform="matrix(1.3748228,0,0,1.3748228,57.553815,24.704538)">
<circle r="3" cy="7.6121001" id="circle8" cx="0"/>
<circle r="3" cx="7.6121001" id="circle10" cy="0"/>
<circle r="3" cy="-7.6121001" id="circle12" cx="0"/>
<circle r="3" cx="-7.6121001" id="circle14" cy="0"/>
<circle r="3" cx="13.2727" cy="-15.7298" id="circle16"/>
<circle r="3" cx="-14.3693" cy="13.5411" id="circle18"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB