Skip to content

Commit ae8724a

Browse files
authored
clean up live view (#34)
* set up / run as unpriviliged 'kernel' user; fix dbus * get rid of no-sandbox warning, run on 8080 in the foreground * disable sound * disable "connected" notification * disable fullscreen, resolution, and pip controls * don't show upper / lower control sections that had tons of padding * default user data with some modifications: - cleared out all bookmarks in the bookmark bar - disabled the bookmark bar in Preferences * ✨ resolution and frame rate control ✨ * kill dbus daemon * denote our mods * add read only flag * test for w/h/fr NaN in one place * unikernel tweaks for running as kernel user * ok cursor * might have to click the mouse... * clickity clack * h/t my boi cursor * only set --no-sandbox --no-zygote if running as root * default run as root false in docker, true in ukc * echo correct * address pr comments * use volimport from onkernel user * wait for chromium window to appear before clicking * i didn't choose the unikernel life, it chose me as always things get complicated going from docker -> unikraft - disable scale to zero - add a sleep because this makes it work * pr feedback
1 parent 6042bde commit ae8724a

File tree

246 files changed

+1970
-68
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

246 files changed

+1970
-68
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.unikraft/

images/chromium-headful/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
bin/
22
recording/
3+
.tmp/

images/chromium-headful/Dockerfile

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ENV DEBIAN_FRONTEND=noninteractive
1313
RUN set -eux; \
1414
apt-get update; \
1515
apt-get install -y \
16-
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
16+
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
1717
&& rm -rf /var/lib/apt/lists/*;
1818
COPY xorg-deps/ /xorg/
1919
# build xf86-video-dummy v0.3.8 with RandR support
@@ -97,12 +97,12 @@ ENV USERNAME=root
9797
RUN set -eux; \
9898
apt-get update; \
9999
apt-get install -y --no-install-recommends \
100-
wget ca-certificates python2 supervisor xclip \
101-
pulseaudio dbus-x11 xserver-xorg-video-dummy \
102-
libcairo2 libxcb1 libxrandr2 libxv1 libopus0 libvpx7 \
103-
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
104-
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
105-
gstreamer1.0-pulseaudio gstreamer1.0-omx; \
100+
wget ca-certificates python2 supervisor xclip xdotool \
101+
pulseaudio dbus-x11 xserver-xorg-video-dummy \
102+
libcairo2 libxcb1 libxrandr2 libxv1 libopus0 libvpx7 \
103+
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
104+
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
105+
gstreamer1.0-pulseaudio gstreamer1.0-omx; \
106106
#
107107
# install libxcvt0 (not available in debian:bullseye)
108108
ARCH=$(dpkg --print-architecture); \
@@ -117,9 +117,9 @@ RUN set -eux; \
117117
#
118118
# make directories for neko
119119
mkdir -p /etc/neko /var/www /var/log/neko \
120-
/tmp/runtime-$USERNAME \
121-
/home/$USERNAME/.config/pulse \
122-
/home/$USERNAME/.local/share/xorg; \
120+
/tmp/runtime-$USERNAME \
121+
/home/$USERNAME/.config/pulse \
122+
/home/$USERNAME/.local/share/xorg; \
123123
chmod 1777 /var/log/neko; \
124124
chown $USERNAME /var/log/neko/ /tmp/runtime-$USERNAME; \
125125
chown -R $USERNAME:$USERNAME /home/$USERNAME; \
@@ -156,5 +156,8 @@ COPY ./wrapper.sh /wrapper.sh
156156
COPY bin/kernel-images-api /usr/local/bin/kernel-images-api
157157
ENV WITH_KERNEL_IMAGES_API=false
158158

159+
RUN useradd -m -s /bin/bash kernel
160+
RUN cp -r ./user-data /home/kernel/user-data
161+
159162
ENTRYPOINT [ "/wrapper.sh" ]
160163

images/chromium-headful/Kraftfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
spec: v0.6
22

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

55
labels:
66
cloud.unikraft.v1.instances/scale_to_zero.policy: "on"

images/chromium-headful/build-unikernel.sh

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
#!/usr/bin/env bash
22

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

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

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

1611
kraft pkg \
17-
--name index.unikraft.io/$image \
12+
--name $UKC_INDEX/$IMAGE \
1813
--plat kraftcloud --arch x86_64 \
1914
--strategy overwrite \
2015
--push \

images/chromium-headful/client/src/app.vue

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@
6969
background: $background-tertiary;
7070
height: $menu-height;
7171
flex-shrink: 0;
72-
display: flex;
72+
// KERNEL: hide it
73+
// display: flex;
74+
display: none;
7375
}
7476
7577
.video-container {
@@ -85,7 +87,9 @@
8587
max-width: 100%;
8688
flex-shrink: 0;
8789
flex-direction: column;
88-
display: flex;
90+
// KERNEL: hide it
91+
// display: flex;
92+
display: none;
8993
9094
.room-menu {
9195
max-width: 100%;
@@ -186,9 +190,9 @@
186190
components: {
187191
'neko-connect': Connect,
188192
'neko-video': Video,
189-
'neko-menu': Menu,
193+
// 'neko-menu': Menu,
190194
//'neko-side': Side,
191-
'neko-controls': Controls,
195+
// 'neko-controls': Controls,
192196
//'neko-members': Members,
193197
//'neko-emotes': Emotes,
194198
//'neko-about': About,
@@ -251,6 +255,59 @@
251255
}
252256
}
253257
258+
// KERNEL: begin custom resolution, frame rate, and readOnly control via query params
259+
260+
// Add a watcher so that when we are connected we can set the resolution from query params
261+
@Watch('connected', { immediate: true })
262+
onConnected(value: boolean) {
263+
if (value) {
264+
this.applyQueryResolution()
265+
}
266+
}
267+
268+
// Read ?width=, ?height=, and optional ?rate= (or their short aliases w/h/r) from the URL
269+
// and set the resolution accordingly. If the current user is an admin we also request the
270+
// server to switch to that resolution.
271+
private applyQueryResolution() {
272+
const params = new URL(location.href).searchParams
273+
274+
// Helper to parse integer query parameters and return `undefined` when the value is not a valid number.
275+
const parseIntSafe = (keys: string[], fallback?: number): number | undefined => {
276+
for (const key of keys) {
277+
const value = params.get(key)
278+
if (value !== null) {
279+
const num = parseInt(value, 10)
280+
if (!isNaN(num)) return num
281+
}
282+
}
283+
return fallback
284+
}
285+
286+
const width = parseIntSafe(['width', 'w'])
287+
const height = parseIntSafe(['height', 'h'])
288+
const rate = parseIntSafe(['rate', 'r'], 30) as number
289+
290+
if (width !== undefined && height !== undefined) {
291+
const resolution = { width, height, rate }
292+
this.$accessor.video.setResolution(resolution)
293+
if (this.$accessor.user && this.$accessor.user.admin) {
294+
this.$accessor.video.screenSet(resolution)
295+
}
296+
}
297+
298+
// Handle readOnly query param (e.g., ?readOnly=true or ?readonly=1)
299+
const readOnlyParam = params.get('readOnly') || params.get('readonly') || params.get('ro')
300+
const readOnly = typeof readOnlyParam === 'string' && ['1', 'true', 'yes'].includes(readOnlyParam.toLowerCase())
301+
if (readOnly) {
302+
// Disable implicit hosting so the user doesn't automatically gain control
303+
this.$accessor.remote.setImplicitHosting(false)
304+
// Lock the session locally to block any input even if hosting is later requested
305+
this.$accessor.remote.setLocked(true)
306+
}
307+
}
308+
309+
// KERNEL: end custom resolution, frame rate, and readOnly control via query params
310+
254311
controlAttempt() {
255312
if (this.shakeKbd || this.$accessor.remote.hosted) return
256313

images/chromium-headful/client/src/components/video.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@
3838
<div ref="aspect" class="player-aspect" />
3939
</div>
4040
<ul v-if="!fullscreen && !hideControls" class="video-menu top">
41+
<!-- KERNEL: disable fullscreen and resolution controls
4142
<li><i @click.stop.prevent="requestFullscreen" class="fas fa-expand"></i></li>
4243
<li v-if="admin"><i @click.stop.prevent="openResolution" class="fas fa-desktop"></i></li>
44+
-->
4345
<li v-if="!controlLocked && !implicitHosting" :class="extraControls || 'extra-control'">
4446
<i
4547
:class="[
@@ -54,15 +56,19 @@
5456
</ul>
5557
<ul v-if="!fullscreen && !hideControls" class="video-menu bottom">
5658
<li v-if="hosting && (!clipboard_read_available || !clipboard_write_available)">
59+
<!-- KERNEL: disable clipboard controls
5760
<i @click.stop.prevent="openClipboard" class="fas fa-clipboard"></i>
61+
-->
5862
</li>
5963
<li>
64+
<!-- KERNEL: disable pip
6065
<i
6166
v-if="pip_available"
6267
@click.stop.prevent="requestPictureInPicture"
6368
v-tooltip="{ content: 'Picture-in-Picture', placement: 'left', offset: 5, boundariesElement: 'body' }"
6469
class="fas fa-external-link-alt"
6570
/>
71+
-->
6672
</li>
6773
<li
6874
v-if="hosting && is_touch_device"

images/chromium-headful/client/src/neko/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,14 @@ export class NekoClient extends BaseClient implements EventEmitter<NekoEvents> {
9797
clean: true,
9898
})
9999

100-
this.$vue.$notify({
101-
group: 'neko',
102-
type: 'success',
103-
title: this.$vue.$t('connection.connected') as string,
104-
duration: 5000,
105-
speed: 1000,
106-
})
100+
// KERNEL: disable notifcation on connected
101+
// this.$vue.$notify({
102+
// group: 'neko',
103+
// type: 'success',
104+
// title: this.$vue.$t('connection.connected') as string,
105+
// duration: 5000,
106+
// speed: 1000,
107+
// })
107108
}
108109

109110
protected [EVENT.DISCONNECTED](reason?: Error) {

images/chromium-headful/client/src/store/chat.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ export const actions = actionTree(
7575

7676
newMessage(store, message: Message) {
7777
if (accessor.settings.chat_sound) {
78-
new Audio('chat.mp3').play().catch(console.error)
78+
// KERNEL: disable sound
79+
// new Audio('chat.mp3').play().catch(console.error)
7980
}
8081
accessor.chat.addMessage(message)
8182
},

images/chromium-headful/common.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -e -o pipefail
3+
4+
# Default UKC_INDEX to index.unikraft.io if not set
5+
UKC_INDEX="${UKC_INDEX:-index.unikraft.io}"
6+
7+
# fail if IMAGE, UKC_TOKEN, UKC_METRO are not set
8+
errormsg=""
9+
for var in IMAGE UKC_TOKEN UKC_METRO; do
10+
if [ -z "${!var}" ]; then
11+
errormsg+="$var "
12+
fi
13+
done
14+
if [ -n "$errormsg" ]; then
15+
echo "Required variables not set: $errormsg"
16+
exit 1
17+
fi

0 commit comments

Comments
 (0)