Skip to content

Commit

Permalink
Add waypipe as a display option
Browse files Browse the repository at this point in the history
Resolves jollheef#15
  • Loading branch information
balsoft committed Jan 31, 2020
1 parent e02edba commit 297ae26
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 104 deletions.
24 changes: 17 additions & 7 deletions appvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func generateVM(path, name string, verbose bool) (realpath, reginfo, qcow2 strin
qcow2 = os.Getenv("HOME") + "/appvm/.fake.qcow2"
if _, err = os.Stat(qcow2); os.IsNotExist(err) {
system.System("qemu-img", "create", "-f", "qcow2", qcow2, "512M")
err = os.Chmod(qcow2, 0400) // qemu run with -snapshot, we only need it for create /dev/vda
err = os.Chmod(qcow2, 0700) // qemu run with -snapshot, we only need it for create /dev/vda
if err != nil {
return
}
Expand Down Expand Up @@ -205,7 +205,7 @@ func isAppvmConfigurationExists(appvmPath, name string) bool {
}

func start(l *libvirt.Libvirt, name string, verbose, online, stateless bool,
args, open string) {
args, open string, protocol string) {

appvmPath := configDir

Expand Down Expand Up @@ -249,7 +249,7 @@ func start(l *libvirt.Libvirt, name string, verbose, online, stateless bool,
if !isAppvmConfigurationExists(appvmPath, name) {
log.Println("No configuration exists for app, " +
"trying to generate")
err := generate(name, "", "", false)
err := generate(name, "", "", false, protocol)
if err != nil {
log.Println("Can't auto generate")
return
Expand All @@ -268,8 +268,16 @@ func start(l *libvirt.Libvirt, name string, verbose, online, stateless bool,
}
}

cmd := exec.Command("virt-viewer", "-c", "qemu:///system", vmName)
cmd.Start()
switch protocol {
case "virt-viewer":
cmd := exec.Command("virt-viewer", "-c", "qemu:///system", vmName)
cmd.Start()
case "waypipe":
waypipe := exec.Command("waypipe", "client")
waypipe.Start()
socat := exec.Command("socat", "TCP-LISTEN:2222,fork,reuseaddr", "UNIX-CONNECT:/tmp/waypipe-client.sock")
socat.Start()
}
}

func stop(l *libvirt.Libvirt, name string) {
Expand Down Expand Up @@ -442,6 +450,7 @@ func main() {
startOpen := startCommand.Flag("open", "Pass file to application").String()
startOffline := startCommand.Flag("offline", "Disconnect").Bool()
startStateless := startCommand.Flag("stateless", "Do not use default state directory").Bool()
startDisplayProtocol := startCommand.Flag("display-protocol", "How application connects to host").Envar("DISPLAY_PROTOCOL").Default("virt-viewer").String()

stopName := kingpin.Command("stop", "Stop application").Arg("name", "Application name").Required().String()
dropName := kingpin.Command("drop", "Remove application data").Arg("name", "Application name").Required().String()
Expand All @@ -451,6 +460,7 @@ func main() {
generateBin := generateCommand.Arg("bin", "Binary").Default("").String()
generateVMName := generateCommand.Flag("vm", "Use VM Name").Default("").String()
generateBuildVM := generateCommand.Flag("build", "Build VM").Bool()
generateDisplayProtocol := generateCommand.Flag("display-protocol", "How application connects to host").Envar("DISPLAY_PROTOCOL").Default("virt-viewer").String()

searchCommand := kingpin.Command("search", "Search for application")
searchName := searchCommand.Arg("name", "Application name").Required().String()
Expand Down Expand Up @@ -484,11 +494,11 @@ func main() {
search(*searchName)
case "generate":
generate(*generateName, *generateBin, *generateVMName,
*generateBuildVM)
*generateBuildVM, *generateDisplayProtocol)
case "start":
start(l, *startName,
!*startQuiet, !*startOffline, *startStateless,
*startArgs, *startOpen)
*startArgs, *startOpen, *startDisplayProtocol)
case "stop":
stop(l, *stopName)
case "drop":
Expand Down
201 changes: 113 additions & 88 deletions base.nix.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,111 +7,136 @@ import (
)

var base_nix = `
{pkgs, ...}:
{
imports = [
<nix/local.nix>
];
services.xserver = {
enable = true;
desktopManager.xterm.enable = false;
displayManager.lightdm = {
enable = true;
autoLogin = {
enable = true;
user = "user";
{ cmd, displayProtocol }:
{ pkgs, config, lib, ... }:
let
protocols = {
waypipe = {
services.mingetty = {
autologinUser = "user";
};
hardware.opengl.enable = true;
fonts.enableDefaultFonts = true;
programs.dconf.enable = true;
programs.bash.loginShellInit = ''
host=$(ip route | grep "^default" | cut -f3 -d" ")
${pkgs.socat}/bin/socat TCP-CONNECT:$host:2222 UNIX-LISTEN:/tmp/waypipe-server.sock &
${pkgs.waypipe}/bin/waypipe server ${pkgs.dbus}/bin/dbus-run-session ${cmd}
'';
environment.variables = {
QT_QPA_PLATFORM = "wayland";
XDG_SESSION_TYPE = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
DISPLAY = ":0";
};
};
windowManager.xmonad.enable = true;
windowManager.default = "xmonad";
};
services.spice-vdagentd.enable = true;
users.extraUsers.user = {
uid = %s;
isNormalUser = true;
extraGroups = [ "audio" ];
createHome = true;
};
virt-viewer = {
services.xserver = {
enable = true;
desktopManager.xterm.enable = false;
displayManager.lightdm = {
enable = true;
autoLogin = {
enable = true;
user = "user";
};
};
displayManager.sessionCommands = "${cmd} &";
windowManager.xmonad.enable = true;
windowManager.default = "xmonad";
};
environment.etc."xmonad.hs".text = ''
import XMonad
main = xmonad defaultConfig
{ workspaces = [ "" ]
, borderWidth = 0
, startupHook = startup
}
services.spice-vdagentd.enable = true;
startup :: X ()
startup = do
spawn "while [ 1 ]; do ${pkgs.spice-vdagent}/bin/spice-vdagent -x; done &"
'';
environment.etc."xmonad.hs".text = ''
import XMonad
main = xmonad defaultConfig
{ workspaces = [ "" ]
, borderWidth = 0
, startupHook = startup
}
startup :: X ()
startup = do
spawn "while [ 1 ]; do ${pkgs.spice-vdagent}/bin/spice-vdagent -x; done &"
'';
systemd.services.home-user-build-xmonad = {
description = "Link xmonad configuration";
serviceConfig = {
ConditionFileNotEmpty = "!/home/user/.xmonad/xmonad.hs";
ExecStart = "/bin/sh -c 'mkdir -p /home/user/.xmonad && ln -s /etc/xmonad.hs /home/user/.xmonad/xmonad.hs'";
RemainAfterExit = "yes";
User = "user";
Restart = "on-failure";
TimeoutSec = 10;
};
wantedBy = [ "multi-user.target" ];
};
systemd.services.home-user-build-xmonad = {
description = "Link xmonad configuration";
serviceConfig = {
ConditionFileNotEmpty = "!/home/user/.xmonad/xmonad.hs";
ExecStart = "/bin/sh -c 'mkdir -p /home/user/.xmonad && ln -s /etc/xmonad.hs /home/user/.xmonad/xmonad.hs'";
RemainAfterExit = "yes";
User = "user";
Restart = "on-failure";
TimeoutSec = 10;
};
wantedBy = [ "multi-user.target" ];
};
systemd.user.services."xrandr" = {
serviceConfig = {
StartLimitBurst = 100;
};
script = "${pkgs.xorg.xrandr}/bin/xrandr --output Virtual-1 --mode $(${pkgs.xorg.xrandr}/bin/xrandr | grep ' ' | head -n 2 | tail -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 }')";
};
systemd.services.mount-home-user = {
description = "Mount /home/user (crutch)";
serviceConfig = {
ExecStart = "/bin/sh -c '/run/current-system/sw/bin/mount -t 9p -o trans=virtio,version=9p2000.L home /home/user'";
RemainAfterExit = "yes";
Type = "oneshot";
User = "root";
systemd.user.timers."xrandr" = {
description = "Auto update resolution crutch";
timerConfig = {
OnBootSec = "1s";
OnUnitInactiveSec = "1s";
Unit = "xrandr.service";
AccuracySec = "1us";
};
wantedBy = ["timers.target"];
};
};
wantedBy = [ "sysinit.target" ];
};
systemd.user.services."xrandr" = {
serviceConfig = {
StartLimitBurst = 100;
common = {
users.extraUsers.user = {
uid = %s;
isNormalUser = true;
extraGroups = [ "audio" ];
createHome = true;
password = "";
};
script = "${pkgs.xorg.xrandr}/bin/xrandr --output Virtual-1 --mode $(${pkgs.xorg.xrandr}/bin/xrandr | grep ' ' | head -n 2 | tail -n 1 | ${pkgs.gawk}/bin/awk '{ print $1 }')";
};
systemd.user.timers."xrandr" = {
description = "Auto update resolution crutch";
timerConfig = {
OnBootSec = "1s";
OnUnitInactiveSec = "1s";
Unit = "xrandr.service";
AccuracySec = "1us";
systemd.services.mount-home-user = {
description = "Mount /home/user (crutch)";
serviceConfig = {
ExecStart =
"/bin/sh -c '/run/current-system/sw/bin/mount -t 9p -o trans=virtio,version=9p2000.L home /home/user'";
RemainAfterExit = "yes";
Type = "oneshot";
User = "root";
};
wantedBy = [ "sysinit.target" ];
};
wantedBy = ["timers.target"];
};
systemd.services."autoballoon" = {
serviceConfig = {
StartLimitBurst = 100;
};
script = ''
${pkgs.procps}/bin/free -m | grep Mem | \
systemd.services."autoballoon" = {
serviceConfig = { StartLimitBurst = 100; };
script = ''
${pkgs.procps}/bin/free -m | grep Mem | \
${pkgs.gawk}/bin/awk '{print $2 "-" $4}' | \
${pkgs.bc}/bin/bc > /home/user/.memory_used
'';
};
'';
};
systemd.timers."autoballoon" = {
description = "Auto update resolution crutch";
timerConfig = {
OnBootSec = "1s";
OnUnitInactiveSec = "1s";
Unit = "autoballoon.service";
AccuracySec = "1us";
systemd.timers."autoballoon" = {
description = "Auto update resolution crutch";
timerConfig = {
OnBootSec = "1s";
OnUnitInactiveSec = "1s";
Unit = "autoballoon.service";
AccuracySec = "1us";
};
wantedBy = [ "timers.target" ];
};
wantedBy = ["timers.target"];
};
in
with lib;
{
imports = [ <nix/local.nix> ];
config = common // protocols.${displayProtocol};
}
`

Expand Down
2 changes: 1 addition & 1 deletion builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

type app struct {
Name string
Nix []byte
Nix []byte
}

var builtin_chromium_nix = app{
Expand Down
2 changes: 1 addition & 1 deletion default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ buildGoPackage rec {

postFixup = ''
wrapProgram $bin/bin/appvm \
--prefix PATH : "${lib.makeBinPath [ nix virt-manager-without-menu ]}"
--prefix PATH : "${lib.makeBinPath [ nix virt-manager-without-menu socat waypipe ]}"
'';

meta = {
Expand Down
12 changes: 6 additions & 6 deletions generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ let
ARGS_FILE=/home/user/.args
ARGS=$(cat $ARGS_FILE)
rm $ARGS_FILE
${application} $ARGS
systemctl poweroff
'';
cmd = "${appRunner}/bin/app";
displayProtocol = "%s";
in {
imports = [
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
<nix/base.nix>
(import <nix/base.nix> { inherit cmd displayProtocol; })
];
services.xserver.displayManager.sessionCommands = "${appRunner}/bin/app &";
}
`

Expand Down Expand Up @@ -76,7 +76,7 @@ func filterDotfiles(files []os.FileInfo) (notHiddenFiles []os.FileInfo) {
return
}

func generate(pkg, bin, vmname string, build bool) (err error) {
func generate(pkg, bin, vmname string, build bool, protocol string) (err error) {
// TODO refactor
var name, channel string

Expand Down Expand Up @@ -178,7 +178,7 @@ func generate(pkg, bin, vmname string, build bool) (err error) {
appFilename = configDir + "/nix/" + name + ".nix"
}

appNixConfig := fmt.Sprintf(template, name, bin)
appNixConfig := fmt.Sprintf(template, name, bin, protocol)

err = ioutil.WriteFile(appFilename, []byte(appNixConfig), 0600)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion local.nix.template.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package main

var local_nix_template = []byte(`
{
#services.xserver.xkbOptions = "ctrl:nocaps";
#services.xserver.xkbOptions = "ctrl:nocaps";
}
`)

0 comments on commit 297ae26

Please sign in to comment.