deskconn

package module
v0.1.0-alpha.ffce955 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 56 Imported by: 0

README

Deskconn

A split operating system where the runtime lives on your computer, the interface lives on any device, and applications can execute locally or in the cloud.

It lets you control Linux desktops remotely (run shells, transfer files, forward ports and more) from any device on your account. Connections are routed through the Deskconn cloud router and can transparently upgrade to direct WebRTC P2P links for lower latency.

Components

The Deskconn ecosystem consists of five pieces. This repository contains the two that run on the managed desktop:

Component Role
deskconnd Desktop daemon. Registers and exposes desktop APIs over WAMP. Runs as a systemd user service.
deskconn Control CLI. Attach desktops, manage files, open shells, forward ports, and more.
deskconn-router Cloud WAMP router. The central hub — every component (CLI, daemon, account service, web app, mobile app) connects through it.
deskconn-account-service Manages user accounts, organizations, and per-device CryptoSign principals.
deskconn-web-app / deskconn-mobile-app Web and mobile interfaces.
How a command reaches your desktop
deskconn CLI
    │  (Unix socket — ~/.deskconn/deskconn.sock)
    ▼
deskconnd (local proxy)
    │  (WebSocket — wss://api.deskconn.com/ws or WebRTC P2P)
    ▼
deskconnd (target device)

The local deskconnd maintains a persistent session to the cloud router per target device. The shell command starts over the routed path and migrates transparently to a direct WebRTC connection in the background once the P2P handshake completes.

Authentication

All cloud connections use CryptoSign (Ed25519). deskconn login generates a keypair, registers the public key with the account service, and stores the private key in ~/.deskconn/id_ed25519.

Installation

curl -fsSL https://get.deskconn.com | sh

This installs deskconn and deskconnd to ~/.local/bin and registers deskconnd as a systemd user service that starts automatically.

Getting started

1. Create an account

Sign up at deskconn.com or via the mobile app.

2. Attach the desktop to the cloud
deskconn attach --username <email> --password <password>
# or read the password from stdin
echo "$PASSWORD" | deskconn attach --username <email> --password-stdin

This creates a realm for the desktop under your account and writes credentials to ~/.deskconn/credentials.json. The daemon picks these up automatically and connects to the cloud router.

3. Log in from the CLI
deskconn login --username <email> --password <password>

Generates an Ed25519 keypair, registers it with the account service, and stores it locally. You only need to do this once per machine; the key is valid for 30 days and is renewed on the next login.

4. List your devices
deskconn ls
deskconn ls --refresh    # fetch the current list from the cloud
deskconn ls --detailed   # show realm, ID, and organisation
5. Open a shell
deskconn shell <device>
deskconn shell <device> --mode p2p      # force WebRTC
deskconn shell <device> --mode routed   # force cloud router

CLI reference

Account
deskconn login    [--username] [--password] [--password-stdin]
deskconn logout
deskconn whoami
deskconn attach   [--name] [--username] [--password] [--password-stdin]
deskconn detach   [--username] [--password] [--password-stdin]
Devices
deskconn ls [--refresh] [--detailed]
deskconn ping <device> [--count N]
Shell & exec
deskconn shell <device> [--mode p2p|routed]
deskconn exec  <device> <command...> [--p2p]
File operations

All file commands accept device:path for remote paths and a bare /path for local paths.

deskconn file ls  <device:path> [--mode p2p|routed]
deskconn file mv  <src> <dst>   [--mode p2p|routed]
deskconn file cp  <src> <dst>   [-r] [--mode p2p|routed]
deskconn file rm  <target>      [--mode p2p|routed]
deskconn file cat <device:path> [--mode p2p|routed]
Port forwarding
# Forward local:remote — traffic on localhost:LOCAL goes to REMOTE on the device
deskconn port forward <device> [-l LOCAL] [-r REMOTE] [--p2p]

# Reverse — the device listens on REMOTE and forwards to localhost:LOCAL
deskconn port reverse <device> [-r REMOTE] [-l LOCAL] [--p2p]
Printing
deskconn print --enable [--host-printers]   # allow this desktop to receive print jobs
deskconn print --disable
deskconn print --status
deskconn print --ls <device>                # list printers on a device
deskconn print <device:printer> <file>      # send a print job
Configuration
deskconn config show
deskconn config set <device> alias <value>
deskconn config unset <device> alias
deskconn config edit
Self-update
deskconn self version
deskconn self update

Development

Build
make build-deskconnd   # builds ./deskconnd
make build-deskconn    # builds ./deskconn

Override the cloud endpoint for local development:

export DESKCONN_CLOUD_URI=ws://localhost:8080/ws
Test
make test

Credential files

All credentials and configuration are stored under ~/.deskconn/:

File Contents
credentials.json Device attach credentials (realm, authid, keypair) used by deskconnd
id_ed25519 CLI private key, username, and key expiry
id_ed25519.pub CLI public key, username, and account name
config.yml Device list and aliases
principals.json Local CryptoSign principals (used by the local WAMP router)
turn_credentials.json Cached TURN server credentials for WebRTC
deskconn.sock Unix socket for local CLI–daemon communication

License

See LICENSE.

Documentation

Index

Constants

View Source
const (
	Realm                            = "io.xconn.deskconn"
	ProcedureDeskconnAttachDesktop   = "io.xconn.deskconn.desktop.attach"
	ProcedureDeskconnDetachDesktop   = "io.xconn.deskconn.desktop.detach"
	TopicDeskconnDesktopDetachFormat = "io.xconn.deskconn.desktop.%s.detach"
	MachineIDPath                    = "/etc/machine-id"
)
View Source
const (
	ProcedureListKeys     = "io.xconn.deskconn.desktop.access.key.list"
	TopicKeyAddedFormat   = "io.xconn.deskconn.desktop.%s.key.add"
	TopicKeyRemovedFormat = "io.xconn.deskconn.desktop.%s.key.remove"
)
View Source
const (
	ProcedureKeyExchange         = "io.xconn.deskconn.deskconnd.key.exchange"
	ProcedureScreenBrightnessGet = "io.xconn.deskconn.deskconnd.screen.brightness.get"
	ProcedureScreenBrightnessSet = "io.xconn.deskconn.deskconnd.screen.brightness.set"
	ProcedureScreenLock          = "io.xconn.deskconn.deskconnd.screen.lock"
	ProcedureScreenIsLocked      = "io.xconn.deskconn.deskconnd.screen.islocked"
	ProcedureShell               = "io.xconn.deskconn.deskconnd.shell"
	ProcedureExec                = "io.xconn.deskconn.deskconnd.exec"
	ProcedureFileBrowse          = "io.xconn.deskconn.deskconnd.file.browse"
	ProcedurePrinterList         = "io.xconn.deskconn.deskconnd.printer.list"
	ProcedurePrinterPrint        = "io.xconn.deskconn.deskconnd.printer.print"
	ProcedureFileRename          = "io.xconn.deskconn.deskconnd.file.rename"
	ProcedureFileDelete          = "io.xconn.deskconn.deskconnd.file.delete"
	ProcedureFileCopy            = "io.xconn.deskconn.deskconnd.file.copy"
	ProcedureFileSearch          = "io.xconn.deskconn.deskconnd.file.search"
	ProcedureDeviceInfo          = "io.xconn.deskconn.deskconnd.device.info"
	ProcedureLogs                = "io.xconn.deskconn.deskconnd.logs"
	ProcedurePing                = "io.xconn.deskconn.deskconnd.ping"
	ProcedureIndexQuery          = "io.xconn.deskconn.deskconnd.index.query"
	ProcedureWallpaperGet        = "io.xconn.deskconn.deskconnd.wallpaper.get"
	ProcedureWallpaperChecksum   = "io.xconn.deskconn.deskconnd.wallpaper.checksum"

	ProcedureMPRISPlayers   = "io.xconn.deskconn.deskconnd.mpris.players"
	ProcedureMPRISPlayPause = "io.xconn.deskconn.deskconnd.mpris.playpause"
	ProcedureMPRISPlay      = "io.xconn.deskconn.deskconnd.mpris.play"
	ProcedureMPRISPause     = "io.xconn.deskconn.deskconnd.mpris.pause"
	ProcedureMPRISNext      = "io.xconn.deskconn.deskconnd.mpris.next"
	ProcedureMPRISPrevious  = "io.xconn.deskconn.deskconnd.mpris.previous"

	ProcedureAudioMute       = "io.xconn.deskconn.deskconnd.audio.mute"
	ProcedureAudioUnmute     = "io.xconn.deskconn.deskconnd.audio.unmute"
	ProcedureAudioToggleMute = "io.xconn.deskconn.deskconnd.audio.togglemute"
	ProcedureAudioIsMuted    = "io.xconn.deskconn.deskconnd.audio.ismuted"

	ProcedureScreenshot           = "io.xconn.deskconn.deskconnd.screenshot"
	ProcedureScreenshotPermission = "io.xconn.deskconn.deskconnd.screenshot.permission"

	ErrInvalidArgument = "wamp.error.invalid_argument"
	ErrOperationFailed = "wamp.error.operation_failed"
	ErrNotAuthorized   = "wamp.error.not_authorized"

	MetaTopicSessionLeave = "wamp.session.on_leave"
)
View Source
const (
	CategoryImages    = "images"
	CategoryVideos    = "videos"
	CategoryPDFs      = "pdfs"
	CategoryTexts     = "texts"
	CategoryDocuments = "documents"
)
View Source
const (
	ProcedureWebRTCOffer     = "io.xconn.webrtc.offer"
	TopicAnswererOnCandidate = "io.xconn.webrtc.answerer.on_candidate"
	TopicOffererOnCandidate  = "io.xconn.webrtc.offerer.on_candidate"

	ProcedurePrincipalCreate = "io.xconn.deskconn.account.principal.create"
	ProcedurePrincipalDelete = "io.xconn.deskconn.account.principal.delete"
	ProcedureAccountGet      = "io.xconn.deskconn.account.get"

	ProcedureProxyShell       = "io.xconn.deskconn.deskconnd.proxy.shell"
	ProcedureProxyExec        = "io.xconn.deskconn.deskconnd.proxy.exec"
	ProcedureProxyFileOp      = "io.xconn.deskconn.deskconnd.proxy.file.op"
	ProcedureProxyDeviceInfo  = "io.xconn.deskconn.deskconnd.proxy.device.info"
	ProcedureProxyLogs        = "io.xconn.deskconn.deskconnd.proxy.logs"
	ProcedureProxyPing        = "io.xconn.deskconn.deskconnd.proxy.ping"
	ProcedureProxyCat         = "io.xconn.deskconn.deskconnd.proxy.file.cat"
	ProcedureLogin            = "io.xconn.deskconn.login"
	ProcedureLogout           = "io.xconn.deskconn.logout"
	ProcedureConnect          = "io.xconn.deskconn.connect"
	ProcedureDisconnect       = "io.xconn.deskconn.disconnect"
	ProcedureDisconnectAll    = "io.xconn.deskconn.disconnect_all"
	ProcedureConnectedDevices = "io.xconn.deskconn.connected_devices"

	ProcedureListDesktop = "io.xconn.deskconn.desktop.list"

	ProcedureAppUpdateCheck = "io.xconn.deskconn.app.update.check"

	ProcedureCoturnCreate = "io.xconn.deskconn.coturn.credentials.create"

	LocalRealm = "io.xconn.deskconn.local"
	CloudRealm = "io.xconn.deskconn"

	ErrAuthenticationFailed = "wamp.error.authentication_failed"

	StunServerURL = "stun:stun.l.google.com:19302"
)
View Source
const ProcedureFileCat = "io.xconn.deskconn.deskconnd.file.cat"
View Source
const (
	ProcedureFileDownload = "io.xconn.deskconn.deskconnd.file.download"
)
View Source
const (
	ProcedureFileUpload = "io.xconn.deskconn.deskconnd.file.upload"
)
View Source
const (
	ProcedurePortForward = "io.xconn.deskconn.deskconnd.port.forward"
)
View Source
const ProcedurePortReverse = "io.xconn.deskconn.deskconnd.port.reverse"

Variables

View Source
var BacklightBasePath = "/sys/class/backlight" //nolint: gochecknoglobals
View Source
var ErrKeyExpired = errors.New("authentication key expired, please login again")

Functions

func AdvertiseService

func AdvertiseService(hostname string, port int, realm string) (*zeroconf.Server, error)

func AllZeros

func AllZeros(b []byte) bool

func Attach

func Attach(username, password, desktopName string) error

func CallFileOp

func CallFileOp(deviceSession *xconn.Session, procedure string, payload []byte) ([]byte, error)

func CaptureScreenshot

func CaptureScreenshot(conn *dbus.Conn) ([]byte, error)

CaptureScreenshot performs the actual portal call. It is intended to be invoked from the foreground helper process.

func CatFile

func CatFile(session *xconn.Session, remotePath string) error

func CatFileViaProxy

func CatFileViaProxy(localSession *xconn.Session, realm, remotePath string, p2p bool) error

func CfgDirectory

func CfgDirectory() (string, error)

func ClientKeyExchangeKeys

func ClientKeyExchangeKeys(privateKey, serverPublicKey []byte) (sendKey, receiveKey []byte, err error)

ClientKeyExchangeKeys derives sendKey ("frontendToBackend") and receiveKey ("backendToFrontend") from the client's private key and the server's public key.

func CloudURI

func CloudURI() string

func ConnectCloudRealm

func ConnectCloudRealm(cfgDirectory string) (*xconn.Session, error)

func ConnectDeviceRealm

func ConnectDeviceRealm(ctx context.Context, realm, cfgDirectory string, useP2P bool) (*xconn.Session, error)

func ConnectWebrtc

func ConnectWebrtc(ctx context.Context, session *xconn.Session, realm, authid, privateKey,
	cfgDirectory string) (*xconn.Session, error)

func CreateX25519KeyPair

func CreateX25519KeyPair() (publicKey []byte, privateKey []byte, err error)

func CredentialsFilePath

func CredentialsFilePath() (string, error)

func DecryptChaCha20Poly1305

func DecryptChaCha20Poly1305(ciphertext, nonce, key []byte) ([]byte, error)

func DecryptPayload

func DecryptPayload(data, key []byte) ([]byte, error)

DecryptPayload decrypts a payload produced by EncryptPayload (nonce+ciphertext).

func DeriveKeyHKDF

func DeriveKeyHKDF(sharedSecret, info []byte) ([]byte, error)

func Detach

func Detach(session *xconn.Session, authID string) error

func DisablePrinting

func DisablePrinting() error

func DisableScreenshot

func DisableScreenshot(cfgDirectory string) error

func EnablePrinterHosting

func EnablePrinterHosting() error

func EnablePrinting

func EnablePrinting() error

func EnableScreenshot

func EnableScreenshot(cfgDirectory string) error

func EncryptChaCha20Poly1305

func EncryptChaCha20Poly1305(plaintext, key []byte) ([]byte, []byte, error)

func EncryptPayload

func EncryptPayload(plaintext, key []byte) ([]byte, error)

EncryptPayload encrypts plaintext and returns nonce+ciphertext concatenated.

func FetchTURNServers

func FetchTURNServers(session *xconn.Session) ([]xconnwebrtc.ICEServer, int64, error)

func ForwardLocalPort

func ForwardLocalPort(ctx context.Context, session *xconn.Session, remotePort, localPort string) error

func GetOrRefreshTURNServers

func GetOrRefreshTURNServers(ctx context.Context, authid, privKey, cfgDirectory string) ([]xconnwebrtc.ICEServer,
	error)

func Login

func Login(session *xconn.Session, username string) error

func PerformKeyExchange

func PerformKeyExchange(privateKey, peerPublicKey []byte) ([]byte, error)

func ProxyCatHandler

func ProxyCatHandler(clientSessions *ClientSessions, cfgDirectory string) xconn.InvocationHandler

func ProxyDeviceInfoHandler

func ProxyDeviceInfoHandler(clientSessions *ClientSessions, cfgDirectory string) xconn.InvocationHandler

func ProxyFileOpHandler

func ProxyFileOpHandler(clientSessions *ClientSessions, cfgDirectory string) xconn.InvocationHandler

func ProxyLogsHandler

func ProxyLogsHandler(proxyCalls *ProxyCalls, clientSessions *ClientSessions,
	cfgDirectory string) xconn.InvocationHandler

ProxyLogsHandler proxies ProcedureLogs using a cloud-first session with async WebRTC upgrade.

func ProxyPingHandler

func ProxyPingHandler(clientSessions *ClientSessions, cfgDirectory string) xconn.InvocationHandler

func ProxyProgressiveInvocationHandler

func ProxyProgressiveInvocationHandler(proxyCalls *ProxyCalls, clientSessions *ClientSessions,
	cfgDirectory, procedure string) xconn.InvocationHandler

func ProxyShellHandler

func ProxyShellHandler(proxyCalls *ProxyCalls, clientSessions *ClientSessions,
	cfgDirectory string) xconn.InvocationHandler

ProxyShellHandler proxies ProcedureShell with transparent PTY migration. On first connection it uses a cloud session for fast start, then upgrades to WebRTC in the background. When WebRTC is ready the daemon migrates the live PTY and stores the WebRTC session for future reuse. If a P2P session is already cached it is used directly with no migration needed.

func PullFiles

func PullFiles(session *xconn.Session, remotePath, localPath string, recursive bool) error

func PushFiles

func PushFiles(session *xconn.Session, localPath, remotePath string, recursive bool) error

func ReadCredentials

func ReadCredentials(cfgDirectory string) (string, string, error)

func RemoveCredentialsFiles

func RemoveCredentialsFiles(cfgDirectory string) error

func ReverseLocalPort

func ReverseLocalPort(ctx context.Context, session *xconn.Session, remotePort, localPort string) error

ReverseLocalPort calls ProcedurePortReverse on the remote device, which listens on remotePort. Incoming connections on the remote are forwarded to localhost:localPort.

func RevokeScreenshotPermission

func RevokeScreenshotPermission(conn *dbus.Conn) error

RevokeScreenshotPermission clears the screenshot entry from the portal permission store.

func ScreenshotEnabled

func ScreenshotEnabled(cfgDirectory string) (bool, error)

func ServerKeyExchange

func ServerKeyExchange(clientPublicKey []byte) (serverPublicKey, sendKey, receiveKey []byte, err error)

ServerKeyExchange generates an ephemeral key pair, performs X25519 with the client's public key, and derives sendKey ("backendToFrontend") and receiveKey ("frontendToBackend"). Returns the server's public key so the caller can forward it to the client.

func SetPrintMode

func SetPrintMode(mode PrintMode) error

func StartInteractiveCommand

func StartInteractiveCommand(session *xconn.Session, realm, procedureName string, args ...string) error

func StreamLogs

func StreamLogs(session *xconn.Session, realm, source string, follow bool, tailN int64, since string) error

func WritePrincipalsToFile

func WritePrincipalsToFile(principals []*CryptosignPrincipal) error

Types

type Audio

type Audio struct {
	// contains filtered or unexported fields
}

func NewAudio

func NewAudio() *Audio

func (*Audio) Close

func (a *Audio) Close()

func (*Audio) IsMuted

func (a *Audio) IsMuted() (bool, error)

func (*Audio) Mute

func (a *Audio) Mute() error

func (*Audio) ToggleMute

func (a *Audio) ToggleMute() (bool, error)

func (*Audio) Unmute

func (a *Audio) Unmute() error

type Authenticator

type Authenticator struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewAuthenticator

func NewAuthenticator(principals []*CryptosignPrincipal) *Authenticator

func (*Authenticator) Authenticate

func (a *Authenticator) Authenticate(request auth.Request) (auth.Response, error)

func (*Authenticator) Methods

func (a *Authenticator) Methods() []auth.Method

func (*Authenticator) RetrievePrincipal

func (a *Authenticator) RetrievePrincipal(authid string) (*CryptosignPrincipal, bool)

func (*Authenticator) SetPrincipal

func (a *Authenticator) SetPrincipal(authid string, principal *CryptosignPrincipal)

func (*Authenticator) SetPrincipals

func (a *Authenticator) SetPrincipals(principals []*CryptosignPrincipal)

func (*Authenticator) SubscribeEvents

func (a *Authenticator) SubscribeEvents(session *xconn.Session, machineID string) error

type CPUTimes

type CPUTimes struct {
	User    float64 `json:"user"`
	System  float64 `json:"system"`
	Nice    float64 `json:"nice"`
	Idle    float64 `json:"idle"`
	IOWait  float64 `json:"iowait"`
	IRQ     float64 `json:"irq"`
	SoftIRQ float64 `json:"softirq"`
	Steal   float64 `json:"steal"`
}

type ClientSessions

type ClientSessions struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewClientSessions

func NewClientSessions() *ClientSessions

func (*ClientSessions) DeleteDeviceSession

func (c *ClientSessions) DeleteDeviceSession(realm string)

func (*ClientSessions) DeviceSessions

func (c *ClientSessions) DeviceSessions() map[string]int64

func (*ClientSessions) Disconnect

func (c *ClientSessions) Disconnect(realm string)

func (*ClientSessions) DisconnectAll

func (c *ClientSessions) DisconnectAll()

func (*ClientSessions) EnsureDeviceSessionWithUpgrade

func (c *ClientSessions) EnsureDeviceSessionWithUpgrade(ctx context.Context, realm,
	cfgDirectory string) (*xconn.Session, <-chan *xconn.Session, error)

EnsureDeviceSessionWithUpgrade is like EnsureDeviceSession but also returns a channel that receives the WebRTC session when the background upgrade completes. If a connected session is already cached the channel is closed immediately.

func (*ClientSessions) EnsureP2PDeviceSession

func (c *ClientSessions) EnsureP2PDeviceSession(ctx context.Context, realm,
	cfgDirectory string) (*xconn.Session, error)

EnsureP2PDeviceSession returns the cached session if one exists. Otherwise it establishes a WebRTC connection synchronously — never falling back to cloud.

func (*ClientSessions) LoggedIn

func (c *ClientSessions) LoggedIn() bool

func (*ClientSessions) Login

func (c *ClientSessions) Login()

func (*ClientSessions) Logout

func (c *ClientSessions) Logout()

func (*ClientSessions) SessionByRealm

func (c *ClientSessions) SessionByRealm(authid string) (*xconn.Session, bool)

func (*ClientSessions) StoreDeviceSession

func (c *ClientSessions) StoreDeviceSession(realm string, session *xconn.Session)

type Config

type Config struct {
	Devices    []Device         `yaml:"devices"`
	Printing   PrintingConfig   `yaml:"printing,omitempty"`
	Screenshot ScreenshotConfig `yaml:"screenshot,omitempty"`
}

type Credentials

type Credentials struct {
	Realm      string `json:"realm"`
	AuthID     string `json:"authid"`
	PublicKey  string `json:"public_key"`
	PrivateKey string `json:"private_key"` // #nosec
}

func EnsureCredentials

func EnsureCredentials() (*Credentials, error)

type CryptosignPrincipal

type CryptosignPrincipal struct {
	AuthID         string   `json:"authid"`
	AuthorizedKeys []string `json:"authorized_keys"`
	AuthRole       string   `json:"authrole"`
}

func ReadPrincipalsFromFile

func ReadPrincipalsFromFile() ([]*CryptosignPrincipal, error)

type Deskconn

type Deskconn struct {
	// contains filtered or unexported fields
}

func NewDeskconn

func NewDeskconn(screen *Screen, mpris *MPRIS, audio *Audio) *Deskconn

func (*Deskconn) HandleFileStreamChannel

func (d *Deskconn) HandleFileStreamChannel(_ string, channel *webrtc.DataChannel)

HandleFileStreamChannel must not block, so it defers the actual work to serveFileStreamChannel, which serves one byte-range read per channel.

func (*Deskconn) Register

func (d *Deskconn) Register(session *xconn.Session) error

func (*Deskconn) StartIndexer

func (d *Deskconn) StartIndexer(ctx context.Context)

StartIndexer starts the background file indexer.

type Device

type Device struct {
	Authid       string       `json:"authid" yaml:"authid"`
	ID           string       `json:"id" yaml:"id"`
	Name         string       `json:"name" yaml:"name"`
	Organization Organization `json:"organization" yaml:"organization"`
	Realm        string       `json:"realm" yaml:"realm"`
	Alias        string       `yaml:"alias"`
	Connected    bool         `yaml:"-" json:"-"`
}

func DevicesFromCfg

func DevicesFromCfg(cfgDirectory string) ([]Device, error)

func FetchDevicesFromCloud

func FetchDevicesFromCloud(cfgDirectory string) ([]Device, error)

type DeviceInfo

type DeviceInfo struct {
	CPUModel    string    `json:"cpu_model"`
	CPUPhysical int       `json:"cpu_physical"`
	CPULogical  int       `json:"cpu_logical"`
	CPUUsages   []float64 `json:"cpu_usages"`
	CPUTimes    CPUTimes  `json:"cpu_times"`

	RAMTotal     uint64 `json:"ram_total"`
	RAMFree      uint64 `json:"ram_free"`
	RAMUsed      uint64 `json:"ram_used"`
	RAMBuffCache uint64 `json:"ram_buff_cache"`
	RAMAvailable uint64 `json:"ram_available"`

	SwapTotal uint64 `json:"swap_total"`
	SwapFree  uint64 `json:"swap_free"`
	SwapUsed  uint64 `json:"swap_used"`

	DiskUsed  uint64 `json:"disk_used"`
	DiskFree  uint64 `json:"disk_free"`
	DiskTotal uint64 `json:"disk_total"`

	NetworkInterfaces []NetworkInterface `json:"network_interfaces"`
}

type FileBrowseResult

type FileBrowseResult struct {
	Path       string      `json:"path"`
	HomePath   string      `json:"home_path"`
	ParentPath string      `json:"parent_path,omitempty"`
	Type       string      `json:"type"`
	Mode       string      `json:"mode"`
	Size       int64       `json:"size"`
	ModTime    time.Time   `json:"mod_time"`
	IsDir      bool        `json:"is_dir"`
	IsSymlink  bool        `json:"is_symlink"`
	LinkTarget string      `json:"link_target,omitempty"`
	Entries    []FileEntry `json:"entries,omitempty"`
}

type FileBrowser

type FileBrowser struct{}

func NewFileBrowser

func NewFileBrowser() *FileBrowser

func (*FileBrowser) Browse

func (f *FileBrowser) Browse(pathArg string) (*FileBrowseResult, error)

func (*FileBrowser) Copy

func (f *FileBrowser) Copy(srcPath, dstPath string) error

func (*FileBrowser) Delete

func (f *FileBrowser) Delete(path string) error

func (*FileBrowser) Rename

func (f *FileBrowser) Rename(oldPath, newPath string) error

func (*FileBrowser) Search

func (f *FileBrowser) Search(pathArg, query string, showHidden bool, sendKey []byte, inv *xconn.Invocation) error

type FileEntry

type FileEntry struct {
	Name       string    `json:"name"`
	Path       string    `json:"path"`
	Type       string    `json:"type"`
	Mode       string    `json:"mode"`
	Size       int64     `json:"size"`
	Hidden     bool      `json:"hidden"`
	ModTime    time.Time `json:"mod_time"`
	IsDir      bool      `json:"is_dir"`
	IsSymlink  bool      `json:"is_symlink"`
	LinkTarget string    `json:"link_target,omitempty"`
	ItemCount  *int      `json:"item_count,omitempty"`
	Thumbnail  string    `json:"thumbnail,omitempty"`
}

type IndexEntry

type IndexEntry struct {
	Path      string    `json:"path"`
	Name      string    `json:"name"`
	Category  string    `json:"category"`
	Size      int64     `json:"size"`
	ModTime   time.Time `json:"mod_time"`
	Thumbnail string    `json:"thumbnail,omitempty"`
}

type IndexQueryResult

type IndexQueryResult struct {
	Status     string            `json:"status"`
	Entries    []IndexEntry      `json:"entries,omitempty"`
	NextCursor map[string]string `json:"next_cursor,omitempty"`
	HasMore    bool              `json:"has_more"`
}

type IndexService

type IndexService struct {
	// contains filtered or unexported fields
}

func NewIndexService

func NewIndexService(cfgDirectory string) (*IndexService, error)

NewIndexService opens (or creates) the bbolt database in cfgDirectory and restores the previous indexing state if one exists.

func (*IndexService) Close

func (s *IndexService) Close()

Close releases the watcher and the bbolt database.

func (*IndexService) Query

func (s *IndexService) Query(categories []string, cursor map[string]string, limit int) (*IndexQueryResult, error)

Query returns a page of indexed entries across the given categories, sorted by modification time (newest first). If categories is empty, all categories are queried. If indexing is still in progress it returns {status:"indexing"} with no entries.

cursor resumes iteration from a previous call's NextCursor. limit caps the number of entries returned; values <= 0 or > maxIndexLimit fall back to defaultIndexLimit.

func (*IndexService) Start

func (s *IndexService) Start(ctx context.Context)

Start launches the background watcher and either the initial indexer (first run) or an incremental sync (subsequent restarts). Guarded by sync.Once.

type MPRIS

type MPRIS struct {
	// contains filtered or unexported fields
}

func NewMPRIS

func NewMPRIS(conn *dbus.Conn) *MPRIS

func (*MPRIS) ListPlayers

func (m *MPRIS) ListPlayers() (map[string]string, error)

func (*MPRIS) Next

func (m *MPRIS) Next() error

func (*MPRIS) NextPlayer

func (m *MPRIS) NextPlayer(name string) error

func (*MPRIS) Pause

func (m *MPRIS) Pause() error

func (*MPRIS) PausePlayer

func (m *MPRIS) PausePlayer(name string) error

func (*MPRIS) Play

func (m *MPRIS) Play() error

func (*MPRIS) PlayPause

func (m *MPRIS) PlayPause() error

func (*MPRIS) PlayPausePlayer

func (m *MPRIS) PlayPausePlayer(name string) error

func (*MPRIS) PlayPlayer

func (m *MPRIS) PlayPlayer(name string) error

func (*MPRIS) Previous

func (m *MPRIS) Previous() error

func (*MPRIS) PreviousPlayer

func (m *MPRIS) PreviousPlayer(name string) error

type NetworkInterface

type NetworkInterface struct {
	Name        string  `json:"name"`
	BytesSentPS float64 `json:"bytes_sent_ps"`
	BytesRecvPS float64 `json:"bytes_recv_ps"`
}

type Organization

type Organization struct {
	ID   string `json:"id" yaml:"id"`
	Name string `json:"name" yaml:"name"`
}

type PrintJobStatus

type PrintJobStatus struct {
	JobID     string `json:"job_id"`
	Printer   string `json:"printer"`
	State     string `json:"state"`
	Message   string `json:"message,omitempty"`
	CreatedAt int64  `json:"created_at"`
}

type PrintMode

type PrintMode string
const (
	PrintModeDisabled PrintMode = "disabled"
	PrintModeAccept   PrintMode = "accept"
	PrintModeHost     PrintMode = "host"
)

func CurrentPrintMode

func CurrentPrintMode() (PrintMode, error)

type Printer

type Printer struct {
	// contains filtered or unexported fields
}

func NewPrinter

func NewPrinter() *Printer

func (*Printer) ExecutePrint

func (p *Printer) ExecutePrint(ctx context.Context, printer string, filename string, data []byte) error

type PrinterInfo

type PrinterInfo struct {
	Name     string `json:"name"`
	PPDModel string `json:"ppd"`
}

type PrintingConfig

type PrintingConfig struct {
	Mode PrintMode `yaml:"mode,omitempty"`
}

type ProxyCall

type ProxyCall struct {
	sync.Mutex
	// contains filtered or unexported fields
}

type ProxyCalls

type ProxyCalls struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewProxyCalls

func NewProxyCalls() *ProxyCalls

func (*ProxyCalls) Delete

func (p *ProxyCalls) Delete(id uint64)

func (*ProxyCalls) Fetch

func (p *ProxyCalls) Fetch(id uint64) (*ProxyCall, bool)

func (*ProxyCalls) Store

func (p *ProxyCalls) Store(id uint64, c *ProxyCall)

type Screen

type Screen struct {
	// contains filtered or unexported fields
}

func NewScreen

func NewScreen(sessionBus, systemBus *dbus.Conn, cfgDirectory string) *Screen

func (*Screen) GetBrightness

func (s *Screen) GetBrightness() (int, error)

func (*Screen) IsLocked

func (s *Screen) IsLocked() (bool, error)

func (*Screen) Lock

func (s *Screen) Lock() error

func (*Screen) Screenshot

func (s *Screen) Screenshot() ([]byte, error)

func (*Screen) SessionBus

func (s *Screen) SessionBus() *dbus.Conn

func (*Screen) SetBrightness

func (s *Screen) SetBrightness(percent int) error

type ScreenshotConfig

type ScreenshotConfig struct {
	Enabled bool `yaml:"enabled,omitempty"`
}

type TURNCredentials

type TURNCredentials struct {
	ExpiresAt  int64    `json:"expires_at"`
	Username   string   `json:"username"`
	Credential string   `json:"credential"`
	URLs       []string `json:"urls"`
}

type Wallpaper

type Wallpaper struct {
	// contains filtered or unexported fields
}

func NewWallpaper

func NewWallpaper(conn *dbus.Conn) *Wallpaper

func (*Wallpaper) HandleChecksum

func (w *Wallpaper) HandleChecksum(_ context.Context, _ *xconn.Invocation) *xconn.InvocationResult

func (*Wallpaper) HandleGet

Directories

Path Synopsis
cmd
deskconn command
deskconnd command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL