Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
12ba047
set up / run as unpriviliged 'kernel' user; fix dbus
rgarcia Jul 14, 2025
601ce91
get rid of no-sandbox warning, run on 8080 in the foreground
rgarcia Jul 14, 2025
5dbd4a5
disable sound
rgarcia Jul 14, 2025
f4cb6bf
disable "connected" notification
rgarcia Jul 14, 2025
33422c6
disable fullscreen, resolution, and pip controls
rgarcia Jul 14, 2025
25f40bd
don't show upper / lower control sections that had tons of padding
rgarcia Jul 14, 2025
a084937
default user data with some modifications:
rgarcia Jul 14, 2025
1dce3cb
✨ resolution and frame rate control ✨
rgarcia Jul 14, 2025
67ac460
kill dbus daemon
rgarcia Jul 14, 2025
7593289
denote our mods
rgarcia Jul 14, 2025
cd4c5ca
add read only flag
rgarcia Jul 14, 2025
a3be73a
test for w/h/fr NaN in one place
rgarcia Jul 15, 2025
f32b8f0
unikernel tweaks for running as kernel user
rgarcia Jul 15, 2025
5aaa6fe
ok cursor
rgarcia Jul 15, 2025
43d739d
might have to click the mouse...
rgarcia Jul 15, 2025
59b1c73
clickity clack
rgarcia Jul 15, 2025
59b95b7
h/t my boi cursor
rgarcia Jul 15, 2025
ea50fcb
Merge branch 'main' into raf/kernel-167-remove-picture-in-picture-fro…
rgarcia Jul 15, 2025
82eceb9
only set --no-sandbox --no-zygote if running as root
rgarcia Jul 16, 2025
5615029
default run as root false in docker, true in ukc
rgarcia Jul 16, 2025
89ef11c
echo correct
rgarcia Jul 16, 2025
dff5ee3
address pr comments
rgarcia Jul 16, 2025
7eaf7ae
use volimport from onkernel user
rgarcia Jul 16, 2025
fef4102
wait for chromium window to appear before clicking
rgarcia Jul 16, 2025
59bbc8b
i didn't choose the unikernel life, it chose me
rgarcia Jul 16, 2025
7b95731
pr feedback
rgarcia Jul 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions images/chromium-headful/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.unikraft/
1 change: 1 addition & 0 deletions images/chromium-headful/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
bin/
recording/
.tmp/
23 changes: 13 additions & 10 deletions images/chromium-headful/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
apt-get update; \
apt-get install -y \
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
&& rm -rf /var/lib/apt/lists/*;
COPY xorg-deps/ /xorg/
# build xf86-video-dummy v0.3.8 with RandR support
Expand Down Expand Up @@ -97,12 +97,12 @@ ENV USERNAME=root
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
wget ca-certificates python2 supervisor xclip \
pulseaudio dbus-x11 xserver-xorg-video-dummy \
libcairo2 libxcb1 libxrandr2 libxv1 libopus0 libvpx7 \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-pulseaudio gstreamer1.0-omx; \
wget ca-certificates python2 supervisor xclip xdotool \
pulseaudio dbus-x11 xserver-xorg-video-dummy \
libcairo2 libxcb1 libxrandr2 libxv1 libopus0 libvpx7 \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-pulseaudio gstreamer1.0-omx; \
#
# install libxcvt0 (not available in debian:bullseye)
ARCH=$(dpkg --print-architecture); \
Expand All @@ -117,9 +117,9 @@ RUN set -eux; \
#
# make directories for neko
mkdir -p /etc/neko /var/www /var/log/neko \
/tmp/runtime-$USERNAME \
/home/$USERNAME/.config/pulse \
/home/$USERNAME/.local/share/xorg; \
/tmp/runtime-$USERNAME \
/home/$USERNAME/.config/pulse \
/home/$USERNAME/.local/share/xorg; \
chmod 1777 /var/log/neko; \
chown $USERNAME /var/log/neko/ /tmp/runtime-$USERNAME; \
chown -R $USERNAME:$USERNAME /home/$USERNAME; \
Expand Down Expand Up @@ -156,5 +156,8 @@ COPY ./wrapper.sh /wrapper.sh
COPY bin/kernel-images-api /usr/local/bin/kernel-images-api
ENV WITH_KERNEL_IMAGES_API=false

RUN useradd -m -s /bin/bash kernel
RUN cp -r ./user-data /home/kernel/user-data

ENTRYPOINT [ "/wrapper.sh" ]

2 changes: 1 addition & 1 deletion images/chromium-headful/Kraftfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
spec: v0.6

runtime: base-compat:latest
runtime: index.unikraft.io/official/base-compat:latest

labels:
cloud.unikraft.v1.instances/scale_to_zero.policy: "on"
Expand Down
11 changes: 3 additions & 8 deletions images/chromium-headful/build-unikernel.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
#!/usr/bin/env bash

# namespace here (onkernel) should match UKC_TOKEN's username
image="onkernel/kernel-cu-test:latest"
source common.sh
set -euo pipefail

# fail if UKC_TOKEN and UKC_METRO are not set
if [ -z "$UKC_TOKEN" ] || [ -z "$UKC_METRO" ]; then
echo "UKC_TOKEN and UKC_METRO must be set"
exit 1
fi
source ../../shared/start-buildkit.sh

# Build the API binary
source ../../shared/build-server.sh "$(pwd)/bin"

kraft pkg \
--name index.unikraft.io/$image \
--name $UKC_INDEX/$IMAGE \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we default to the public unikraft index to make this easier for folks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

--plat kraftcloud --arch x86_64 \
--strategy overwrite \
--push \
Expand Down
65 changes: 61 additions & 4 deletions images/chromium-headful/client/src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@
background: $background-tertiary;
height: $menu-height;
flex-shrink: 0;
display: flex;
// KERNEL: hide it
// display: flex;
display: none;
}

.video-container {
Expand All @@ -85,7 +87,9 @@
max-width: 100%;
flex-shrink: 0;
flex-direction: column;
display: flex;
// KERNEL: hide it
// display: flex;
display: none;

.room-menu {
max-width: 100%;
Expand Down Expand Up @@ -186,9 +190,9 @@
components: {
'neko-connect': Connect,
'neko-video': Video,
'neko-menu': Menu,
// 'neko-menu': Menu,
//'neko-side': Side,
'neko-controls': Controls,
// 'neko-controls': Controls,
//'neko-members': Members,
//'neko-emotes': Emotes,
//'neko-about': About,
Expand Down Expand Up @@ -251,6 +255,59 @@
}
}

// KERNEL: begin custom resolution, frame rate, and readOnly control via query params

// Add a watcher so that when we are connected we can set the resolution from query params
@Watch('connected', { immediate: true })
onConnected(value: boolean) {
if (value) {
this.applyQueryResolution()
}
}

// Read ?width=, ?height=, and optional ?rate= (or their short aliases w/h/r) from the URL
// and set the resolution accordingly. If the current user is an admin we also request the
// server to switch to that resolution.
private applyQueryResolution() {
const params = new URL(location.href).searchParams

// Helper to parse integer query parameters and return `undefined` when the value is not a valid number.
const parseIntSafe = (keys: string[], fallback?: number): number | undefined => {
for (const key of keys) {
const value = params.get(key)
if (value !== null) {
const num = parseInt(value, 10)
if (!isNaN(num)) return num
}
}
return fallback
}

const width = parseIntSafe(['width', 'w'])
const height = parseIntSafe(['height', 'h'])
const rate = parseIntSafe(['rate', 'r'], 30) as number

if (width !== undefined && height !== undefined) {
const resolution = { width, height, rate }
this.$accessor.video.setResolution(resolution)
if (this.$accessor.user && this.$accessor.user.admin) {
this.$accessor.video.screenSet(resolution)
}
}

// Handle readOnly query param (e.g., ?readOnly=true or ?readonly=1)
const readOnlyParam = params.get('readOnly') || params.get('readonly') || params.get('ro')
const readOnly = typeof readOnlyParam === 'string' && ['1', 'true', 'yes'].includes(readOnlyParam.toLowerCase())
if (readOnly) {
// Disable implicit hosting so the user doesn't automatically gain control
this.$accessor.remote.setImplicitHosting(false)
// Lock the session locally to block any input even if hosting is later requested
this.$accessor.remote.setLocked(true)
}
}

// KERNEL: end custom resolution, frame rate, and readOnly control via query params

controlAttempt() {
if (this.shakeKbd || this.$accessor.remote.hosted) return

Expand Down
6 changes: 6 additions & 0 deletions images/chromium-headful/client/src/components/video.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@
<div ref="aspect" class="player-aspect" />
</div>
<ul v-if="!fullscreen && !hideControls" class="video-menu top">
<!-- KERNEL: disable fullscreen and resolution controls
<li><i @click.stop.prevent="requestFullscreen" class="fas fa-expand"></i></li>
<li v-if="admin"><i @click.stop.prevent="openResolution" class="fas fa-desktop"></i></li>
-->
<li v-if="!controlLocked && !implicitHosting" :class="extraControls || 'extra-control'">
<i
:class="[
Expand All @@ -54,15 +56,19 @@
</ul>
<ul v-if="!fullscreen && !hideControls" class="video-menu bottom">
<li v-if="hosting && (!clipboard_read_available || !clipboard_write_available)">
<!-- KERNEL: disable clipboard controls
<i @click.stop.prevent="openClipboard" class="fas fa-clipboard"></i>
-->
</li>
<li>
<!-- KERNEL: disable pip
<i
v-if="pip_available"
@click.stop.prevent="requestPictureInPicture"
v-tooltip="{ content: 'Picture-in-Picture', placement: 'left', offset: 5, boundariesElement: 'body' }"
class="fas fa-external-link-alt"
/>
-->
</li>
<li
v-if="hosting && is_touch_device"
Expand Down
15 changes: 8 additions & 7 deletions images/chromium-headful/client/src/neko/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ export class NekoClient extends BaseClient implements EventEmitter<NekoEvents> {
clean: true,
})

this.$vue.$notify({
group: 'neko',
type: 'success',
title: this.$vue.$t('connection.connected') as string,
duration: 5000,
speed: 1000,
})
// KERNEL: disable notifcation on connected
// this.$vue.$notify({
// group: 'neko',
// type: 'success',
// title: this.$vue.$t('connection.connected') as string,
// duration: 5000,
// speed: 1000,
// })
}

protected [EVENT.DISCONNECTED](reason?: Error) {
Expand Down
3 changes: 2 additions & 1 deletion images/chromium-headful/client/src/store/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ export const actions = actionTree(

newMessage(store, message: Message) {
if (accessor.settings.chat_sound) {
new Audio('chat.mp3').play().catch(console.error)
// KERNEL: disable sound
// new Audio('chat.mp3').play().catch(console.error)
}
accessor.chat.addMessage(message)
},
Expand Down
14 changes: 14 additions & 0 deletions images/chromium-headful/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -e -o pipefail

# fail if IMAGE, UKC_TOKEN, UKC_METRO, UKC_INDEX are not set
errormsg=""
for var in IMAGE UKC_TOKEN UKC_METRO UKC_INDEX; do
if [ -z "${!var}" ]; then
errormsg+="$var "
fi
done
if [ -n "$errormsg" ]; then
echo "Required variables not set: $errormsg"
exit 1
fi
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
36 changes: 36 additions & 0 deletions images/chromium-headful/image-chromium/user-data/Default/Bookmarks
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"checksum": "b6d02a93fae2ae0863aac8814bd10763",
"roots": {
"bookmark_bar": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Bookmarks bar",
"type": "folder"
},
"other": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other bookmarks",
"type": "folder"
},
"synced": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile bookmarks",
"type": "folder"
}
},
"version": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"checksum": "b6d02a93fae2ae0863aac8814bd10763",
"roots": {
"bookmark_bar": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Bookmarks bar",
"type": "folder"
},
"other": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other bookmarks",
"type": "folder"
},
"synced": {
"children": [],
"date_added": "13397001174416633",
"date_last_used": "0",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile bookmarks",
"type": "folder"
}
},
"version": 1
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:40.347 6d Creating DB /home/kernel/user-data/Default/Extension Rules since it was missing.
2025/07/14-21:35:40.358 6d Reusing MANIFEST /home/kernel/user-data/Default/Extension Rules/MANIFEST-000001
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:40.359 6d Creating DB /home/kernel/user-data/Default/Extension Scripts since it was missing.
2025/07/14-21:35:40.367 6d Reusing MANIFEST /home/kernel/user-data/Default/Extension Scripts/MANIFEST-000001
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:40.386 61 Creating DB /home/kernel/user-data/Default/Extension State since it was missing.
2025/07/14-21:35:40.394 61 Reusing MANIFEST /home/kernel/user-data/Default/Extension State/MANIFEST-000001
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:43.655 61 Creating DB /home/kernel/user-data/Default/GCM Store/Encryption since it was missing.
2025/07/14-21:35:43.668 61 Reusing MANIFEST /home/kernel/user-data/Default/GCM Store/Encryption/MANIFEST-000001
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:43.648 61 Creating DB /home/kernel/user-data/Default/GCM Store since it was missing.
2025/07/14-21:35:43.654 61 Reusing MANIFEST /home/kernel/user-data/Default/GCM Store/MANIFEST-000001
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Empty file.
Empty file.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MANIFEST-000001
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2025/07/14-21:35:40.334 7 Creating DB /home/kernel/user-data/Default/Local Storage/leveldb since it was missing.
2025/07/14-21:35:40.357 7 Reusing MANIFEST /home/kernel/user-data/Default/Local Storage/leveldb/MANIFEST-000001
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"net":{"network_qualities":{"CAESABiAgICA+P////8B":"4G"}}}
Loading
Loading