Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a354a27
fix: improve ui and add docs
Sep 28, 2023
9a4f505
fix: migration for states
Sep 30, 2023
c609625
fix: remove debugger statement from spice lib
tinyzimmer Oct 13, 2023
6fc9653
linting: fix remainging ui linting errors
tinyzimmer Oct 13, 2023
1b388a4
fix: try chainging language package name
tinyzimmer Oct 13, 2023
62b918e
fix: backend needs to strip the /static prefix with the UI updates
tinyzimmer Oct 14, 2023
bda5898
ci: move runs to self-hosted runners
tinyzimmer Oct 14, 2023
459e543
ci: fix to use absolute path to quasar binary
tinyzimmer Oct 14, 2023
aca5378
docs: bump go version
Oct 17, 2023
0c7c605
docs: fix broken links
Oct 17, 2023
9bd19c7
docs: add gif to introduction
Oct 17, 2023
3a1e451
docs: remove title
Oct 17, 2023
325d2de
docs: fix demo link
Oct 17, 2023
804873f
docs: simple github button
Oct 17, 2023
68ebeeb
docs: add bg
Oct 17, 2023
cc38afe
Merge branch 'main' of github.com:webmeshproj/webmesh-vdi into rework-ui
tinyzimmer Oct 20, 2023
a0d5d02
draft: scaffold frontend logic for idtoken login
tinyzimmer Oct 20, 2023
d1d3fb0
draft: fill in id-token login logic
tinyzimmer Oct 20, 2023
732a65f
Merge branch 'main' of github.com:webmeshproj/webmesh-vdi into rework-ui
tinyzimmer Oct 20, 2023
cee6062
fix: use /api/auth_methods to retrieve auth method before login
tinyzimmer Oct 20, 2023
f673783
fix: dont strip prefix from static path
tinyzimmer Oct 20, 2023
a8f0f72
tidy: quasar config tidying
tinyzimmer Oct 20, 2023
79d18d1
tidy: makefile cleanup
tinyzimmer Oct 20, 2023
5fcf636
fix: bring routes definitions up to the latest
tinyzimmer Oct 20, 2023
b2b213f
fix: axios data does not have a JSON method
tinyzimmer Oct 20, 2023
07448ff
tidy: cleanup quasar conf
tinyzimmer Oct 20, 2023
dd09939
fix: get auth method was using wrong data type
tinyzimmer Oct 20, 2023
3d724f2
Merge branch 'main' of github.com:webmeshproj/webmesh-vdi into rework-ui
tinyzimmer Oct 20, 2023
345bb0e
Merge branch 'main' of github.com:webmeshproj/webmesh-vdi into rework-ui
tinyzimmer Oct 20, 2023
6a1834a
Merge branch 'main' of github.com:webmeshproj/webmesh-vdi into rework-ui
tinyzimmer Oct 20, 2023
e06d6f7
fix: fixes to webmesh auth
tinyzimmer Oct 20, 2023
28c9915
fix: update tags in desktop template
tinyzimmer Oct 20, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/audio-proxy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ env:
jobs:
build:
name: Build Proxy Images
runs-on: ubuntu-latest
runs-on: self-hosted
permissions:
contents: "write"
id-token: "write"
Expand Down
22 changes: 11 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ env:
jobs:
build:
name: Build Images
runs-on: ubuntu-latest
runs-on: self-hosted
permissions:
contents: "write"
id-token: "write"
Expand All @@ -45,15 +45,15 @@ jobs:
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup Build Cache
uses: actions/cache@v3
with:
key: ${{ runner.os }}-build-${{ hashFiles(env.CACHE_DEP_PATH) }}
restore-keys: ${{ runner.os }}-build-${{ env.GO_VERSION }}-
path: |
~/go/pkg
~/.cache/go-build
ui/app/node_modules
# - name: Setup Build Cache
# uses: actions/cache@v3
# with:
# key: ${{ runner.os }}-build-${{ hashFiles(env.CACHE_DEP_PATH) }}
# restore-keys: ${{ runner.os }}-build-${{ env.GO_VERSION }}-
# path: |
# ~/go/pkg
# ~/.cache/go-build
# ui/app/node_modules

- name: Login to GHCR
uses: docker/login-action@v3
Expand Down Expand Up @@ -92,7 +92,7 @@ jobs:
shell: bash
run: |
yarn global add @quasar/cli
cd ui/app && yarn install && quasar build
cd ui/app && yarn install && $(yarn global bin)/quasar build

- name: Build and Push Manager Image
uses: docker/build-push-action@v5
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ env:
jobs:
setup:
name: Tests
runs-on: ubuntu-latest
runs-on: self-hosted
steps:
- name: Checkout Code
uses: actions/checkout@v4
Expand All @@ -25,15 +25,15 @@ jobs:
check-latest: true
cache: false

- name: Setup Test Cache
uses: actions/cache@v3
with:
key: ${{ runner.os }}-tests-go-${{ env.GO_VERSION }}-${{ hashFiles(env.CACHE_DEP_PATH) }}
restore-keys: ${{ runner.os }}-tests-go-${{ env.GO_VERSION }}-
path: |
~/go/pkg
~/go/bin
~/.cache/go-build
# - name: Setup Test Cache
# uses: actions/cache@v3
# with:
# key: ${{ runner.os }}-tests-go-${{ env.GO_VERSION }}-${{ hashFiles(env.CACHE_DEP_PATH) }}
# restore-keys: ${{ runner.os }}-tests-go-${{ env.GO_VERSION }}-
# path: |
# ~/go/pkg
# ~/go/bin
# ~/.cache/go-build

- name: Static Analysis
uses: golangci/golangci-lint-action@v3
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ build-manager:
## make build-app # Build the app docker image.
build-app:
VERSION=$(VERSION) $(GORELEASER) build --single-target --id app $(BUILD_ARGS)
cd ui/app && yarn install && quasar build
cd ui/app && yarn install && yarn build
docker build . \
-f build/Dockerfile.app \
-t $(APP_IMAGE) \
Expand Down
217 changes: 22 additions & 195 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,213 +1,40 @@
# Webmesh Desktop

A Virtual Desktop Infrastructure running on Kubernetes. With soon to come webmesh integration.
<br>
<p align="center">
<img width="140" src="./docs/logo.png" alt="Icon">
</p>

[![Go Report Card](https://goreportcard.com/badge/github.com/webmeshproj/webmesh-vdi)](https://goreportcard.com/report/github.com/webmeshproj/webmesh-vdi)
![Tests](https://github.com/webmeshproj/webmesh-vdi/actions/workflows/tests.yml/badge.svg)
![Build](https://github.com/webmeshproj/webmesh-vdi/actions/workflows/build.yml/badge.svg)
[![Go Reference](https://pkg.go.dev/badge/github.com/webmeshproj/webmesh-vdi.svg)](https://pkg.go.dev/github.com/webmeshproj/webmesh-vdi)
<h1 align="center" style="font-size: 5vmin;">
<strong>
Webmesh Desktop
</strong>
</h1>

**ATTENTION:** The `helm` chart repository has been moved to a [separate repo](https://github.com/kvdi/helm-charts) to tidy things up here more. To update your repository you can do the following:
<h3 align="center">
Desktops at scale
</h3>

```sh
helm repo remove kvdi
helm repo add kvdi https://kvdi.github.io/helm-charts/charts
helm repo update

helm install kvdi kvdi/kvdi # yes, that's a lot of kvdi
```
<h3 align="center"><a href="https://site.org">Documentation</a> - <a href="https://discord.gg/vpkFjGuwYC">Join us on Discord</a></h3>

This project has reached a point where I am not going to be making enormous changes all the time anymore. As such I am tagging a "stable" release and incrementing from there.
That still doesn't mean I highly recommend it's usage, but rather I am relatively confident in its overall stability.
<div align="center">

- [API Reference](doc/appv1.md)
- [RBAC Reference](doc/rbacv1.md)
- [Templates Reference](doc/desktopsv1.md)
- [Installing](#Installing)
- [Standalone](#Install-standalone)
- [Kubernetes](#Install-to-a-pre-existing-cluster)
- [Helm](#helm)
- [Bundle](#bundle-manifest)
- [Kustomize](#kustomize)
- [CLI](doc/kvdictl/kvdictl.md)
- [Upgrading](#Upgrading)
- [Building Desktop Images](build/desktops/README.md)
- [Security](#security)
- [Screenshots/Video](doc/screenshots.md)
- [Donating](#donating)
![](https://github.com/kvdi/kvdi/workflows/Tests/badge.svg)
![](https://github.com/kvdi/kvdi/workflows/Build/badge.svg)
[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-rounded)](https://pkg.go.dev/github.com/kvdi/kvdi)

If you are interested in helping out or just simply launching a design discussion, feel free to send PRs and/or issues.
I wrote up a [`CONTRIBUTING`](CONTRIBUTING.md) doc just outlining some of the stuff I have in mind that would need to be acomplished for this to be considered "stable".
</div>

## Features

- Containerized user desktops running on Kubernetes with no virtualization required (`libvirt` options may come in the future). All traffic between the end user and the "desktop" is encrypted.

- Persistent user data
A Virtual Desktop Infrastructure on powered by Wireguard™️ with Webmesh

- Audio playback and microphone support

- File transfer to/from "desktop" sessions. Directories get archived into a gzipped tarball prior to download.
![Video](./docs/screenshots/demo.gif)

- RBAC system for managing user access to templates, roles, users, namespaces, serviceaccounts, etc.

- MFA Support
## Getting started

- Configurable backend for internal secrets. Currently `vault` or Kubernetes Secrets
See the [installation guide](TODO)

- Use built-in local authentication, LDAP, or OpenID.

- App metrics to either scrape externally or view in the UI. More details in the `helm` doc.

### TODO

- "App Profiles" - I have a POC implementation on `main` but it is still pretty buggy
- DOSBox/Game profiles could be cool...same as "App Profiles"
- ARM64 support. Should be easy, but the build files will need some shuffling.
- UI could use a serious makeover from someone who actually knows what they are doing

## Requirements

For building and running locally you will need:

- `go >= 1.14`
- `docker`

## Installing

### Install standalone

If you don't have access to a Kubernetes cluster, or you just want to try `kVDI` out on a VM real quick, there is a script in this repository for setting up kVDI using `k3s`.
It requires the instance running the script to have `docker` and the `dialog` package installed.

_If you have an existing `k3s` installation, the ingress may not work since this script assumes `kVDI` will be the only LoadBalancer installed._

```bash
# Download the script from this repository.
curl -JLO https://raw.githubusercontent.com/kvdi/kvdi/main/deploy/architect/kvdi-architect.sh
# Run the script. You will be prompted via dialogs to make configuration changes.
bash kvdi-architect.sh # Use --help to see all available options.
```

_NOTE: This script is fairly new and still has some bugs_

### Install to a pre-existing cluster

#### Helm

For more complete installation instructions see the `helm` chart docs [here](https://github.com/kvdi/helm-charts/blob/main/charts/kvdi/README.md) for available configuration options.

The [API Reference](doc/appv1.md) can also be used for details on `kVDI` app-level configurations.

```bash
helm repo add kvdi https://kvdi.github.io/helm-charts/charts # Add the kvdi charts repo
helm repo update # Sync your repositories

# Install kVDI
helm install kvdi kvdi/kvdi
```

It will take a minute or two for all the parts to start running after the install command.
Once the app is launched, you can retrieve the admin password from `kvdi-admin-secret` in your cluster (if you are using `ldap` auth, log in with a user in one of the `adminGroups`).

To access the app interface either do a `port-forward` (`make forward-app` is another helper for that when developing locally with `kind`), or go to the "LoadBalancer" IP of the service.

By default there are no desktop templates configured. If you'd like, you can apply the ones in `deploy/examples/example-desktop-templates.yaml` to get started quickly.

#### Bundle Manifest

There is a manifest in this repository that will **just** lay down the manager instance, its dependencies, and all of the CRDs.
You can then create a [VDICluster](doc/appv1.md#VDIClusterSpec) object manually to spin up an actual application instance.

To install the manifest:

```bash
export KVDI_VERSION=v0.3.6

kubectl apply -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/deploy/bundle.yaml --validate=false
```

#### Kustomize

The `kustomize` manifests in this repository are generated by `kubebuilder` and are usable as well similar to the [Bundle Manifest](#bundle-manifest).
They can be found in the [config](config/) directory in this repository.

## Upgrading

Most of the time you can just run a regular helm upgrade to update your deployment manifests to the latest images.

```bash
helm upgrade kvdi kvdi/kvdi --version v0.3.6
```

However, sometimes there may be changes to the CRDs, though I will always do my best to make sure they are backwards compatible.
Due to the way helm manages CRDs, it will ignore changes to those on an existing installation.
You can get around this by applying the CRDs for the version you are upgrading to directly from this repo.

For example:

```bash
export KVDI_VERSION=v0.3.6

kubectl apply \
-f https://github.com/kvdi/kvdi/raw/${KVDI_VERSION}/config/crd/bases/app.kvdi.io_vdiclusters.yaml \
-f https://github.com/kvdi/kvdi/raw/${KVDI_VERSION}/config/crd/bases/desktops.kvdi.io_sessions.yaml \
-f https://github.com/kvdi/kvdi/raw/${KVDI_VERSION}/config/crd/bases/desktops.kvdi.io_templates.yaml \
-f https://github.com/kvdi/kvdi/raw/${KVDI_VERSION}/config/crd/bases/rbac.kvdi.io_vdiroles.yaml
```

When there is a change to one or more CRDs, it will be mentioned in the notes for that release.

## Building and Running Locally

The `Makefile` contains helpers for testing the full solution locally using `k3d`. Run `make help` to see all the available options.

_If you choose to pull the images from the registry instead of building and loading first - you probably want to set `VERSION=latest` (or a previous version) in your environment also.
The `Makefile` is usually pointed at the next version to be released and published images may not exist yet_.

```bash
# Builds all the docker images (optional, they are also available in the github registry)
$> make build-all
# Spin up a kind cluster for local testing
$> make test-cluster
# Load all the docker images into the kind cluster (optional for same reason as build)
$> make load-all
# Deploy the manager, kvdi, and setup the example templates
$> make deploy example-vdi-templates
# To test using custom helm values
$> HELM_ARGS="-f my_values.yaml" make deploy
```

After the manager has started the `app` instance, get the IP of its service with `kubectl get svc` to access the frontend, or you can run `make-forward-app` to start a local port-forward.

If not using anonymous auth, look for `kvdi-admin-secret` to retrieve the `admin` password.

## Security

All traffic between processes is encrypted with mTLS.
The UI for the "desktop" containers is placed behind a VNC server listening on a UNIX socket and a sidecar to the container will proxy validated websocket connections to it.

![img](doc/kvdi_arch.png)

User authentication is provided by "providers". There are currently three implementations:

- `local-auth` : A `passwd` like file is kept in the Secrets backend (k8s or vault) mapping users to roles and password hashes. This is primarily meant for development, but you could secure your environment in a way to make it viable for a small number of users.

- `ldap-auth` : An LDAP/AD server is used for autenticating users. VDIRoles can be tied to
security groups in LDAP via annotations. When a user is authenticated, their groups are queried to see if they are bound to any VDIRoles.

- `oidc-auth` : An OpenID or OAuth provider is used for authenticating users. If using an Oauth provider, it must support the `openid` scope. When a user is authenticated, a configurable `groups` claim is requested from the provider that can be mapped to VDIRoles similarly to `ldap-auth`. If the provider does not support a `groups` claim, you can configure `kVDI` to allow all authenticated users.

All three authentication methods also support MFA.

# Donating

kVDI started as just a fun project, but as more people have started to use it, I've really wanted to find more time to continue making improvements.
Unfortunately, it just doesn't pay the bills so I can only really settle into it when I have nothing else going on.
I've set up a Patreon and an ETH wallet if people would like to support further development:

- Patreon: [![Support me on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dkvdi%26type%3Dpatrons&style=flat)](https://www.patreon.com/kvdi?fan_landing=true)

- ETH: `0xdFC61298BdFe4a6F7fb1eFae5Da27d905c1bD172`

Feel free to email me at the address on my Github profile if you have any other questions.
2 changes: 1 addition & 1 deletion apis/app/v1/vdicluster_auth_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (c *VDICluster) AnonymousAllowed() bool {
// if no other options are defined.
func (c *VDICluster) IsUsingLocalAuth() bool {
if c.Spec.Auth != nil {
return c.Spec.Auth.LocalAuth != nil && !c.IsUsingLDAPAuth() && !c.IsUsingOIDCAuth()
return c.Spec.Auth.LocalAuth != nil && !c.IsUsingLDAPAuth() && !c.IsUsingOIDCAuth() && !c.IsUsingWebmeshAuth()
}
return true
}
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.app
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM scratch

ARG TARGETARCH TARGETOS
ADD dist/app_${TARGETOS}_${TARGETARCH}*/app /app
ADD ui/app/dist/spa /static
ADD ui/app/dist /static
ADD ui/swagger.json /static/swagger.json
ADD ui/app/src/statics /static/statics

Expand Down
2 changes: 1 addition & 1 deletion deploy/examples/example-desktop-templates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ spec:
allowFileTransfer: true
tags:
os: ubuntu
desktop: xfce4
desktop: kde
applications: minimal
---
apiVersion: desktops.kvdi.io/v1
Expand Down
Empty file added docs/.nojekyll
Empty file.
25 changes: 25 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Webmesh Desktop

A Virtual Desktop Infrastructure on top of Webmesh.

**It is fast because it is built on top of Webmesh, which is powered by Wiregaurd™️**

**It is scalable for all needs because it runs on Kubernetes**

**It is easy to use!**

![gif](/screenshots/demo.gif?raw=true)



## Features

- Containerized user desktops running on Kubernetes with no virtualization required (`libvirt` options may come in the future). All traffic between the end user and the "desktop" is encrypted.
- Persistent user data
- Audio playback and microphone support
- File transfer to/from "desktop" sessions. Directories get archived into a gzipped tarball prior to download.
- RBAC system for managing user access to templates, roles, users, namespaces, serviceaccounts, etc.
- MFA Support
- Configurable backend for internal secrets. Currently `vault` or Kubernetes Secrets
- Use built-in local authentication, LDAP, or OpenID.
- App metrics to either scrape externally or view in the UI. More details in the `helm` doc.
3 changes: 3 additions & 0 deletions docs/_navbar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* [Home](/)
* [Join us on Discord](https://discord.gg/vpkFjGuwYC)
* [Github](https://github.com/webmeshproj/webmesh-vdi)
Loading