Initial commit
This commit is contained in:
commit
968d09e362
88 changed files with 2323 additions and 0 deletions
30
os/layers/contestant/hooks/live/2010-contestant.hook.chroot
Executable file
30
os/layers/contestant/hooks/live/2010-contestant.hook.chroot
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# Set root password.
|
||||
chpasswd --encrypted <<< 'root:@contestant_root_password@'
|
||||
|
||||
# Set chromium homepage.
|
||||
sed -i 's|"homepage": ".*"|"homepage": "https://contest.soi.ch/"|' /etc/chromium/master_preferences
|
||||
sed -i 's|"homepage_is_newtabpage": true,|"homepage_is_newtabpage": false,|' /etc/chromium/master_preferences
|
||||
|
||||
# Disable Bluetooth.
|
||||
systemctl disable bluetooth.service
|
||||
|
||||
# Disable sleep.
|
||||
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
|
||||
|
||||
# Disable panels in gnome-control-center.
|
||||
DISABLE_DESKTOP="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
|
||||
|
||||
# Enable the live system configuration script at boot.
|
||||
systemctl enable live-config.service
|
||||
|
||||
# Disable kexec-tools services.
|
||||
# We want to load kexec manually, and execution of kexec is already done by systemd.
|
||||
systemctl disable kexec-load.service
|
||||
systemctl disable kexec.service
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Disable automount
|
||||
[org/gnome/desktop/media-handling]
|
||||
automount = false
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Disable blank screen
|
||||
[org/gnome/desktop/session]
|
||||
idle-delay = uint32 0
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Disable lock on blank screen
|
||||
[org/gnome/desktop/screensaver]
|
||||
lock-enabled = false
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# Disable suspend when inactive
|
||||
[org/gnome/settings-daemon/plugins/power]
|
||||
sleep-inactive-ac-type = 'nothing'
|
||||
sleep-inactive-battery-type = 'nothing'
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Disable "Updates available" notifications and auto updates.
|
||||
# Updates which require reboot are useless on live systems,
|
||||
# and other updates would be installed on each boot.
|
||||
[org/gnome/software]
|
||||
allow-updates = false
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[org/gnome/shell]
|
||||
enabled-extensions = ['contest-lock@soi.ch', 'user-indicator@soi.ch']
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Disable locking the screen
|
||||
[org/gnome/desktop/lockdown]
|
||||
disable-lock-screen = true
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"policies": {
|
||||
"OverrideFirstRunPage": "",
|
||||
"NoDefaultBookmarks": true,
|
||||
"DisableProfileImport": true,
|
||||
"Preferences": {
|
||||
"datareporting.policy.dataSubmissionPolicyBypassNotification": true,
|
||||
"security.default_personal_cert": "Select Automatically"
|
||||
},
|
||||
"Homepage": {
|
||||
"URL": "https://contest.soi.ch/",
|
||||
"StartPage": "homepage"
|
||||
},
|
||||
"DisplayBookmarksToolbar": true,
|
||||
"Bookmarks": [
|
||||
{
|
||||
"Title": "Contest",
|
||||
"URL": "https://contest.soi.ch/",
|
||||
"Placement": "toolbar"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Show a root password prompt for these actions:
|
||||
// - change network settings
|
||||
// - hibernate
|
||||
// - change package download proxy
|
||||
// - mount removable storage, perform other disk operations
|
||||
|
||||
polkit.addRule(function (action, subject) {
|
||||
if (
|
||||
action.id.indexOf("org.freedesktop.ModemManager1.") === 0 ||
|
||||
action.id.indexOf("org.freedesktop.NetworkManager.") === 0 ||
|
||||
action.id === "org.freedesktop.login1.hibernate" ||
|
||||
action.id === "org.freedesktop.packagekit.system-network-proxy-configure" ||
|
||||
action.id.indexOf("org.freedesktop.udisks2.") === 0
|
||||
) {
|
||||
return polkit.Result.AUTH_ADMIN;
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
PasswordAuthentication no
|
||||
AllowUsers root
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=custom configuration of live system during boot.
|
||||
Before=basic.target
|
||||
After=local-fs.target systemd-tmpfiles-setup.service
|
||||
DefaultDependencies=no
|
||||
ConditionKernelCommandLine=boot=live
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/bin/live-config
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[Time]
|
||||
NTP=contest.soi.ch
|
||||
49
os/layers/contestant/includes.chroot/usr/local/bin/install-client-cert
Executable file
49
os/layers/contestant/includes.chroot/usr/local/bin/install-client-cert
Executable 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 use this profile
|
||||
cat > "$userhome/.mozilla/firefox/profiles.ini" <<EOF
|
||||
[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 ""
|
||||
36
os/layers/contestant/includes.chroot/usr/local/bin/live-config
Executable file
36
os/layers/contestant/includes.chroot/usr/local/bin/live-config
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
LIVE_HOSTNAME=debian
|
||||
LIVE_USERNAME=contestant
|
||||
LIVE_USER_FULLNAME="Contestant"
|
||||
|
||||
# Set hostname.
|
||||
echo "${LIVE_HOSTNAME}" > /etc/hostname
|
||||
hostname "${LIVE_HOSTNAME}"
|
||||
|
||||
# Create hosts file.
|
||||
cat > /etc/hosts <<EOF
|
||||
127.0.0.1 localhost ${LIVE_HOSTNAME}
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
fe00::0 ip6-localnet
|
||||
ff00::0 ip6-mcastprefix
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
EOF
|
||||
|
||||
# Create ssh host key.
|
||||
ssh-keygen -q -f /etc/ssh/ssh_host_ed25519_key -N "" -t ed25519
|
||||
|
||||
# Create user.
|
||||
adduser --disabled-password --gecos "$LIVE_USER_FULLNAME" "$LIVE_USERNAME"
|
||||
|
||||
# Enable auto login.
|
||||
sed -i \
|
||||
-e "s/^[# ]*AutomaticLoginEnable *=.*/AutomaticLoginEnable = true/g" \
|
||||
-e "s/^[# ]*AutomaticLogin *=.*/AutomaticLogin = $LIVE_USERNAME/g" \
|
||||
-e "s/^[# ]*TimedLoginEnable *=.*/TimedLoginEnable = true/g" \
|
||||
-e "s/^[# ]*TimedLogin *=.*/TimedLogin = $LIVE_USERNAME/g" \
|
||||
-e "s/^[# ]*TimedLoginDelay *=.*/TimedLoginDelay = 5/g" \
|
||||
/etc/gdm3/daemon.conf
|
||||
16
os/layers/contestant/includes.chroot/usr/local/bin/reboot-interactive
Executable file
16
os/layers/contestant/includes.chroot/usr/local/bin/reboot-interactive
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# Reboot with kexec.
|
||||
# This has the advantage that we don't need to go through the system boot menu,
|
||||
# which is especially useful when the boot menu is password protected.
|
||||
# However, we currently can't preserve the squashfs in RAM across kexec,
|
||||
# so the boot USB stick needs to be plugged in before rebooting.
|
||||
|
||||
kexec --kexec-file-syscall --load /vmlinuz --initrd=/initrd.img --append="$(cat /proc/cmdline)"
|
||||
|
||||
if XDG_RUNTIME_DIR="/run/user/$(id -u contestant)" runuser -u contestant -- zenity --question --title="Reboot?" --text="Press Enter after inserting the boot USB stick."
|
||||
then
|
||||
reboot
|
||||
fi
|
||||
|
|
@ -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://contest.soi.ch/" ICON="data:image/png;base64,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">Contest</A>
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
// 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 or later.
|
||||
|
||||
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');
|
||||
|
||||
// Force a redraw of the entire label widget. Without this, there sometimes
|
||||
// appears a small artifact to the right of the text, which is only visible
|
||||
// every other second. This seems to be a bug in the rendering engine itself.
|
||||
labelCountdown.queue_redraw();
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
@ -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", "43" ],
|
||||
"url": ""
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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", "43" ],
|
||||
"url": ""
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.panel-bin {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
12
os/layers/contestant/package-lists/contestant.list.chroot
Normal file
12
os/layers/contestant/package-lists/contestant.list.chroot
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Remote access
|
||||
openssh-server
|
||||
rsync
|
||||
|
||||
# Firewall
|
||||
nftables
|
||||
|
||||
# Reboot with kexec
|
||||
kexec-tools
|
||||
|
||||
# For importing client certificate
|
||||
libnss3-tools
|
||||
62
os/layers/participant/archives/sublime-text.key.chroot
Normal file
62
os/layers/participant/archives/sublime-text.key.chroot
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
McvDuGKIXk111Z3nrF4DeIIc/U6ICQ==
|
||||
=CCk2
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
os/layers/participant/archives/sublime-text.list.chroot
Normal file
1
os/layers/participant/archives/sublime-text.list.chroot
Normal file
|
|
@ -0,0 +1 @@
|
|||
deb http://download.sublimetext.com/ apt/stable/
|
||||
19
os/layers/participant/archives/vscode.key.chroot
Normal file
19
os/layers/participant/archives/vscode.key.chroot
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.7 (GNU/Linux)
|
||||
|
||||
mQENBFYxWIwBCADAKoZhZlJxGNGWzqV+1OG1xiQeoowKhssGAKvd+buXCGISZJwT
|
||||
LXZqIcIiLP7pqdcZWtE9bSc7yBY2MalDp9Liu0KekywQ6VVX1T72NPf5Ev6x6DLV
|
||||
7aVWsCzUAF+eb7DC9fPuFLEdxmOEYoPjzrQ7cCnSV4JQxAqhU4T6OjbvRazGl3ag
|
||||
OeizPXmRljMtUUttHQZnRhtlzkmwIrUivbfFPD+fEoHJ1+uIdfOzZX8/oKHKLe2j
|
||||
H632kvsNzJFlROVvGLYAk2WRcLu+RjjggixhwiB+Mu/A8Tf4V6b+YppS44q8EvVr
|
||||
M+QvY7LNSOffSO6Slsy9oisGTdfE39nC7pVRABEBAAG0N01pY3Jvc29mdCAoUmVs
|
||||
ZWFzZSBzaWduaW5nKSA8Z3Bnc2VjdXJpdHlAbWljcm9zb2Z0LmNvbT6JATUEEwEC
|
||||
AB8FAlYxWIwCGwMGCwkIBwMCBBUCCAMDFgIBAh4BAheAAAoJEOs+lK2+EinPGpsH
|
||||
/32vKy29Hg51H9dfFJMx0/a/F+5vKeCeVqimvyTM04C+XENNuSbYZ3eRPHGHFLqe
|
||||
MNGxsfb7C7ZxEeW7J/vSzRgHxm7ZvESisUYRFq2sgkJ+HFERNrqfci45bdhmrUsy
|
||||
7SWw9ybxdFOkuQoyKD3tBmiGfONQMlBaOMWdAsic965rvJsd5zYaZZFI1UwTkFXV
|
||||
KJt3bp3Ngn1vEYXwijGTa+FXz6GLHueJwF0I7ug34DgUkAFvAs8Hacr2DRYxL5RJ
|
||||
XdNgj4Jd2/g6T9InmWT0hASljur+dJnzNiNCkbn9KbX7J/qK1IbR8y560yRmFsU+
|
||||
NdCFTW7wY0Fb1fWJ+/KTsC4=
|
||||
=J6gs
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
os/layers/participant/archives/vscode.list.chroot
Normal file
1
os/layers/participant/archives/vscode.list.chroot
Normal file
|
|
@ -0,0 +1 @@
|
|||
deb http://packages.microsoft.com/repos/code stable main
|
||||
31
os/layers/participant/bootloaders/grub-pc/config.cfg
Normal file
31
os/layers/participant/bootloaders/grub-pc/config.cfg
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
set timeout=5
|
||||
|
||||
# Everything below is copied from the default config.
|
||||
|
||||
set default=0
|
||||
|
||||
if [ x$feature_default_font_path = xy ] ; then
|
||||
font=unicode
|
||||
else
|
||||
font=$prefix/unicode.pf2
|
||||
fi
|
||||
|
||||
# Copied from the netinst image
|
||||
if loadfont $font ; then
|
||||
set gfxmode=800x600
|
||||
set gfxpayload=keep
|
||||
insmod efi_gop
|
||||
insmod efi_uga
|
||||
insmod video_bochs
|
||||
insmod video_cirrus
|
||||
else
|
||||
set gfxmode=auto
|
||||
insmod all_video
|
||||
fi
|
||||
|
||||
insmod gfxterm
|
||||
insmod png
|
||||
|
||||
source /boot/grub/theme.cfg
|
||||
|
||||
terminal_output gfxterm
|
||||
33
os/layers/participant/bootloaders/syslinux_common/splash.svg
Normal file
33
os/layers/participant/bootloaders/syslinux_common/splash.svg
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480">
|
||||
<rect x="0" y="0" width="640" height="480" fill="#000"/>
|
||||
<g transform="translate(90, 90) scale(4)">
|
||||
<circle r="13.75" fill="none" stroke="#303030" stroke-width="2.5"/>
|
||||
<path fill="none" stroke="#1eadf5" stroke-width="2" d="M7.6121 0 0 -7.6121 13.2727 -15.7298M-7.6121 0 7.6121 0 0 7.6121 -7.6121 0 -14.3693 13.5411"/>
|
||||
<g fill="#1862ff">
|
||||
<circle r="3" cy="7.6121"/>
|
||||
<circle r="3" cx="7.6121"/>
|
||||
<circle r="3" cy="-7.6121"/>
|
||||
<circle r="3" cx="-7.6121"/>
|
||||
<circle r="3" cx="13.2727" cy="-15.7298"/>
|
||||
<circle r="3" cx="-14.3693" cy="13.5411"/>
|
||||
</g>
|
||||
</g>
|
||||
<g style="font-family: 'DejaVu Sans'; fill: #fff;">
|
||||
<text style="font-weight:bold;font-size:20px;"
|
||||
x="191" y="48">@PROJECT@ @VERSION@ (@DISTRIBUTION@)</text>
|
||||
<text style="font-weight:bold;font-size:20px;"
|
||||
x="191" y="68">@ARCHITECTURE@</text>
|
||||
<text style="font-weight:bold;font-size:16px;"
|
||||
x="191" y="108">Built: @YEAR@-@MONTH@-@DAY@ @HOUR@:@MINUTE@:@SECOND@ @TIMEZONE@</text>
|
||||
<text style="font-weight:normal;font-size:10px;"
|
||||
x="191" y="140">linux: @LINUX_VERSIONS@</text>
|
||||
<!--<text style="font-weight:normal;font-size:10px;"
|
||||
x="191" y="156">live-build: @LIVE_BUILD_VERSION@</text>
|
||||
<text style="font-weight:normal;font-size:10px;"
|
||||
x="191" y="172">live-boot: @LIVE_BOOT_VERSION@</text>
|
||||
<text style="font-weight:normal;font-size:10px;"
|
||||
x="191" y="188">live-config: @LIVE_CONFIG_VERSION@</text>
|
||||
<text style="font-weight:normal;font-size:10px;"
|
||||
x="191" y="204">live-tools: @LIVE_TOOLS_VERSION@</text>-->
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
47
os/layers/participant/hooks/live/2000-participant.hook.chroot
Executable file
47
os/layers/participant/hooks/live/2000-participant.hook.chroot
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# Update dconf database after having put files in /etc/dconf/.
|
||||
dconf update
|
||||
|
||||
# Configure timezone.
|
||||
TIMEZONE=Europe/Zurich
|
||||
echo "$TIMEZONE" > /etc/timezone
|
||||
ln -sf /usr/share/zoneinfo/"$TIMEZONE" /etc/localtime
|
||||
|
||||
# Install VS Code extensions.
|
||||
VSCODE_EXTENSIONS="ms-python.python ms-vscode.cpptools swissolyinfo.soicode"
|
||||
mkdir /etc/skel/.vscode
|
||||
chown nobody:nogroup /etc/skel/.vscode
|
||||
for ext in $VSCODE_EXTENSIONS; do
|
||||
runuser -u nobody -- code --user-data-dir=/tmp/vsc.tmp \
|
||||
--extensions-dir=/etc/skel/.vscode/extensions \
|
||||
--install-extension="$ext"
|
||||
done
|
||||
chown -R root:root /etc/skel/.vscode
|
||||
rm -rf /tmp/vsc.tmp
|
||||
|
||||
# Enable codeblocks template.
|
||||
sed -i 's|// project wizards|RegisterWizard(wizProject, _T("soi"), _T("A SOI task"), _T("Console"));|' /usr/share/codeblocks/templates/wizard/config.script
|
||||
|
||||
# Add a default keyring to avoid a prompt to create one when launching Chromium.
|
||||
mkdir -p /etc/skel/.local/share/keyrings/
|
||||
chmod og= /etc/skel/.local/share/keyrings/
|
||||
echo -n "Default_keyring" > /etc/skel/.local/share/keyrings/default
|
||||
cat > /etc/skel/.local/share/keyrings/Default_keyring.keyring <<EOF
|
||||
[keyring]
|
||||
display-name=Default keyring
|
||||
ctime=0
|
||||
mtime=0
|
||||
lock-on-idle=false
|
||||
lock-after=false
|
||||
EOF
|
||||
chmod og= /etc/skel/.local/share/keyrings/Default_keyring.keyring
|
||||
|
||||
# Patch bug in live-boot.
|
||||
# This is fixed upstream: https://salsa.debian.org/live-team/live-boot/-/commit/2cb049fb7502d11f344d14c567aab2592f19e77b
|
||||
# Once we pull in the fix through an upgrade, we can remove the patch here.
|
||||
if [ -f /lib/live/boot/9990-toram-todisk.sh ]; then
|
||||
sed -i 's|dev="/dev/shm"|dev="tmpfs"|g' /lib/live/boot/9990-toram-todisk.sh
|
||||
fi
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[org/gnome/desktop/background]
|
||||
picture-uri = 'file:///usr/local/share/backgrounds/wallpaper-soi.svg'
|
||||
picture-uri-dark = 'file:///usr/local/share/backgrounds/wallpaper-soi-dark.svg'
|
||||
picture-options = 'zoom'
|
||||
primary-color = '#e6e6e6'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[org/gnome/shell]
|
||||
favorite-apps = ['firefox-esr.desktop', 'gnome-terminal.desktop', 'nautilus.desktop']
|
||||
|
|
@ -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')]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
user-db:user
|
||||
system-db:local
|
||||
0
os/layers/participant/includes.chroot/etc/motd
Normal file
0
os/layers/participant/includes.chroot/etc/motd
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-80 -80 160 160" width="3840" height="3840">
|
||||
<title>Swiss Olympiad in Informatics</title>
|
||||
<rect fill="#2a2a2a" x="-100" y="-100" width="200" height="200"/>
|
||||
<circle r="13.75" fill="none" stroke="#101010" stroke-width="2.5"/>
|
||||
<path fill="none" stroke="#1eadf5" stroke-width="2" d="M7.6121 0 0 -7.6121 13.2727 -15.7298M-7.6121 0 7.6121 0 0 7.6121 -7.6121 0 -14.3693 13.5411"/>
|
||||
<g fill="#1862ff">
|
||||
<circle r="3" cy="7.6121"/>
|
||||
<circle r="3" cx="7.6121"/>
|
||||
<circle r="3" cy="-7.6121"/>
|
||||
<circle r="3" cx="-7.6121"/>
|
||||
<circle r="3" cx="13.2727" cy="-15.7298"/>
|
||||
<circle r="3" cx="-14.3693" cy="13.5411"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 654 B |
|
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-80 -80 160 160" width="3840" height="3840">
|
||||
<title>Swiss Olympiad in Informatics</title>
|
||||
<rect fill="#e6e6e6" x="-100" y="-100" width="200" height="200"/>
|
||||
<circle r="13.75" fill="none" stroke="#303030" stroke-width="2.5"/>
|
||||
<path fill="none" stroke="#1eadf5" stroke-width="2" d="M7.6121 0 0 -7.6121 13.2727 -15.7298M-7.6121 0 7.6121 0 0 7.6121 -7.6121 0 -14.3693 13.5411"/>
|
||||
<g fill="#1862ff">
|
||||
<circle r="3" cy="7.6121"/>
|
||||
<circle r="3" cx="7.6121"/>
|
||||
<circle r="3" cy="-7.6121"/>
|
||||
<circle r="3" cx="-7.6121"/>
|
||||
<circle r="3" cx="13.2727" cy="-15.7298"/>
|
||||
<circle r="3" cx="-14.3693" cy="13.5411"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 654 B |
3
os/layers/participant/package-lists/live.list.chroot
Normal file
3
os/layers/participant/package-lists/live.list.chroot
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
live-boot
|
||||
|
||||
# This file overrides a default list to remove live-config.
|
||||
41
os/layers/participant/package-lists/participant.list.chroot
Normal file
41
os/layers/participant/package-lists/participant.list.chroot
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# firmware
|
||||
firmware-linux amd64-microcode intel-microcode
|
||||
firmware-iwlwifi firmware-brcm80211 firmware-realtek
|
||||
|
||||
# system
|
||||
systemd-timesyncd
|
||||
locales
|
||||
zstd
|
||||
wpasupplicant
|
||||
wireless-regdb
|
||||
|
||||
# desktop
|
||||
gnome-core
|
||||
xdg-user-dirs-gtk
|
||||
network-manager-gnome
|
||||
# needed for ejecting UBS sticks in nautilus
|
||||
eject
|
||||
|
||||
# shell utilities
|
||||
htop unzip
|
||||
|
||||
# software for participants
|
||||
firefox-esr chromium-l10n
|
||||
codeblocks emacs geany gedit joe kate kdevelop nano vim vim-gtk3
|
||||
gcc g++ gdb ddd valgrind python3 pypy3
|
||||
evince gnome-terminal konsole xterm byobu make cmake
|
||||
nautilus-extension-gnome-terminal
|
||||
file-roller
|
||||
# for drawing on screenshots
|
||||
drawing
|
||||
# documentation
|
||||
info manpages-dev gcc-doc gdb-doc
|
||||
# from third-party repositories
|
||||
sublime-text code
|
||||
# requested by participants (gnome-tweaks can be used e.g. to change the function of Caps Lock key)
|
||||
gnome-tweaks fonts-firacode
|
||||
|
||||
# translations
|
||||
manpages-de manpages-fr manpages-it
|
||||
gcc-12-locales
|
||||
firefox-esr-l10n-de firefox-esr-l10n-fr firefox-esr-l10n-it
|
||||
1
os/layers/participant/preseed/participant.cfg.chroot
Normal file
1
os/layers/participant/preseed/participant.cfg.chroot
Normal file
|
|
@ -0,0 +1 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# Fasttrack is needed for VirtualBox.
|
||||
deb https://fasttrack.debian.net/debian-fasttrack/ @DISTRIBUTION@-fasttrack main contrib
|
||||
|
|
@ -0,0 +1 @@
|
|||
ethdetect
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# Install the noauth PAM profile.
|
||||
groupadd noauth
|
||||
pam-auth-update --enable noauth
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
echo "inventory-hostname" >> .disk/udeb_include
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[org/gnome/login-screen]
|
||||
logo = '/usr/local/share/images/login-screen-logo.svg'
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
user-db:user
|
||||
system-db:gdm
|
||||
file-db:/usr/share/gdm/greeter-dconf-defaults
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Connecting to a WiFi in the gnome-shell quick settings prompts for an admin
|
||||
// password without this rule.
|
||||
// https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7378
|
||||
|
||||
polkit.addRule(function (action, subject) {
|
||||
if (action.id === "org.freedesktop.NetworkManager.settings.modify.system") {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
17
os/layers/training-installer/includes.chroot/usr/local/bin/install-config
Executable file
17
os/layers/training-installer/includes.chroot/usr/local/bin/install-config
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# Set up apt lists.
|
||||
cp -rT /usr/local/share/target-sources /etc/apt/sources.list.d
|
||||
rm /etc/apt/sources.list
|
||||
|
||||
USERNAME=soi
|
||||
USER_FULLNAME="SOI"
|
||||
# Password: soi
|
||||
USER_PASSWORD='$y$j9T$h5VhMd4KkdmbxdZD1gO0N/$1hvwZgO8pQw13Xd6jaNXbtkbqVOC4W/ia/KXOcCGYvB'
|
||||
|
||||
# Create user.
|
||||
adduser --disabled-password --gecos "$USER_FULLNAME" "$USERNAME"
|
||||
usermod -p "$USER_PASSWORD" "$USERNAME"
|
||||
adduser "$USERNAME" noauth
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-260 -20 520 40" width="1300" height="100">
|
||||
<title>Swiss Olympiad in Informatics</title>
|
||||
<circle r="13.75" fill="none" stroke="#101010" stroke-width="2.5"/>
|
||||
<path fill="none" stroke="#1eadf5" stroke-width="2" d="M7.6121 0 0 -7.6121 13.2727 -15.7298M-7.6121 0 7.6121 0 0 7.6121 -7.6121 0 -14.3693 13.5411"/>
|
||||
<g fill="#1862ff">
|
||||
<circle r="3" cy="7.6121"/>
|
||||
<circle r="3" cx="7.6121"/>
|
||||
<circle r="3" cy="-7.6121"/>
|
||||
<circle r="3" cx="-7.6121"/>
|
||||
<circle r="3" cx="13.2727" cy="-15.7298"/>
|
||||
<circle r="3" cx="-14.3693" cy="13.5411"/>
|
||||
</g>
|
||||
<g style="font-family: 'DejaVu Sans'; font-size: 5px; fill: #fff;">
|
||||
<text x="40" y="-9">This laptop is property of the Swiss Olympiad in Informatics. Contact: info@soi.ch</text>
|
||||
<text x="40" y="1">Dieser Laptop ist Eigentum der Schweizer Informatikolympiade. Kontakt: info@soi.ch</text>
|
||||
<text x="40" y="11">Software version: @date@</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 937 B |
|
|
@ -0,0 +1,11 @@
|
|||
Types: deb deb-src
|
||||
URIs: http://deb.debian.org/debian
|
||||
Suites: bookworm bookworm-updates
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
|
||||
Types: deb deb-src
|
||||
URIs: http://deb.debian.org/debian-security
|
||||
Suites: bookworm-security
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Name: Accept noauth users without any authentication
|
||||
Default: yes
|
||||
Priority: 512
|
||||
Auth-Type: Primary
|
||||
Auth:
|
||||
[success=end default=ignore] pam_succeed_if.so user ingroup noauth
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Disable mountmedia, because that can make the cdrom mount fail.
|
||||
# Not sure why there are two conflicting mounting mechanisms in Debian Installer
|
||||
# (mountmedia with /media and cdrom-detect with /cdrom).
|
||||
exit 1
|
||||
28
os/layers/training-installer/includes.installer/preseed.cfg
Normal file
28
os/layers/training-installer/includes.installer/preseed.cfg
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#_preseed_V1
|
||||
|
||||
d-i debian-installer/language string en
|
||||
d-i debian-installer/country string CH
|
||||
d-i debian-installer/locale string en_US.UTF-8
|
||||
|
||||
d-i keyboard-configuration/xkb-keymap select ch
|
||||
|
||||
d-i hw-detect/load_firmware boolean false
|
||||
|
||||
d-i netcfg/enable boolean false
|
||||
d-i netcfg/get_domain string
|
||||
|
||||
d-i passwd/root-login boolean false
|
||||
d-i passwd/user-fullname string Admin
|
||||
d-i passwd/username string superstofl
|
||||
d-i passwd/user-password-crypted password @install_admin_password@
|
||||
|
||||
d-i partman-auto/method string regular
|
||||
d-i partman-auto/init_automatically_partition select some_device
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman/choose_partition select finish
|
||||
|
||||
d-i apt-setup/use_mirror boolean false
|
||||
|
||||
d-i grub-installer/only_debian boolean true
|
||||
|
||||
d-i preseed/late_command string in-target /usr/local/bin/install-config
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# This file overrides a default list to remove live-config.
|
||||
# For the installer, we don't need any live packages,
|
||||
# they would just be removed again by the installer.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
sudo
|
||||
|
||||
# Make Secure Boot work
|
||||
grub-efi-amd64-signed
|
||||
|
||||
# Firmware updates through gnome-software
|
||||
fwupd fwupd-signed
|
||||
|
||||
# Low battery charge notifications, battery info
|
||||
gnome-power-manager
|
||||
|
||||
# Run virtual machines with Gnome Boxes
|
||||
gnome-boxes qemu-system-x86 qemu-utils libvirt-daemon-system
|
||||
|
||||
# Run virtual machines with VirtualBox
|
||||
virtualbox-qt
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# Enable the live system configuration script at boot.
|
||||
systemctl enable live-config.service
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Disable lock on blank screen
|
||||
[org/gnome/desktop/screensaver]
|
||||
lock-enabled = false
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Disable "Updates available" notifications and auto updates.
|
||||
# Updates which require reboot are useless on live systems,
|
||||
# and other updates would be installed on each boot.
|
||||
[org/gnome/software]
|
||||
allow-updates = false
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=custom configuration of live system during boot.
|
||||
Before=basic.target
|
||||
After=local-fs.target systemd-tmpfiles-setup.service
|
||||
DefaultDependencies=no
|
||||
ConditionKernelCommandLine=boot=live
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/local/bin/live-config
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
||||
44
os/layers/training-live/includes.chroot/usr/local/bin/live-config
Executable file
44
os/layers/training-live/includes.chroot/usr/local/bin/live-config
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
LIVE_HOSTNAME=debian
|
||||
|
||||
LIVE_USERNAME=soi
|
||||
LIVE_USER_FULLNAME="SOI live"
|
||||
# Password: soi
|
||||
LIVE_USER_PASSWORD='$y$j9T$h5VhMd4KkdmbxdZD1gO0N/$1hvwZgO8pQw13Xd6jaNXbtkbqVOC4W/ia/KXOcCGYvB'
|
||||
|
||||
# Set hostname.
|
||||
echo "${LIVE_HOSTNAME}" > /etc/hostname
|
||||
hostname "${LIVE_HOSTNAME}"
|
||||
|
||||
# Create hosts file.
|
||||
cat > /etc/hosts <<EOF
|
||||
127.0.0.1 localhost ${LIVE_HOSTNAME}
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
fe00::0 ip6-localnet
|
||||
ff00::0 ip6-mcastprefix
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
EOF
|
||||
|
||||
# Create user.
|
||||
adduser --disabled-password --gecos "$LIVE_USER_FULLNAME" "$LIVE_USERNAME"
|
||||
usermod -p "$LIVE_USER_PASSWORD" "$LIVE_USERNAME"
|
||||
adduser "$LIVE_USERNAME" sudo
|
||||
|
||||
# Disable sudo password prompt.
|
||||
cat > /etc/sudoers.d/10_customize <<EOF
|
||||
# Do not ask for password
|
||||
Defaults !authenticate
|
||||
EOF
|
||||
|
||||
# Enable auto login.
|
||||
sed -i \
|
||||
-e "s/^[# ]*AutomaticLoginEnable *=.*/AutomaticLoginEnable = true/g" \
|
||||
-e "s/^[# ]*AutomaticLogin *=.*/AutomaticLogin = $LIVE_USERNAME/g" \
|
||||
-e "s/^[# ]*TimedLoginEnable *=.*/TimedLoginEnable = true/g" \
|
||||
-e "s/^[# ]*TimedLogin *=.*/TimedLogin = $LIVE_USERNAME/g" \
|
||||
-e "s/^[# ]*TimedLoginDelay *=.*/TimedLoginDelay = 5/g" \
|
||||
/etc/gdm3/daemon.conf
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
sudo
|
||||
|
||||
# Show progress while copying squashfs to RAM.
|
||||
rsync
|
||||
Loading…
Add table
Add a link
Reference in a new issue