Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ydotool: refactor ; nixos/ydotool: init module & nixosTest #303745

Merged
merged 4 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2405.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m

- [isolate](https://github.com/ioi/isolate), a sandbox for securely executing untrusted programs. Available as [security.isolate](#opt-security.isolate.enable).

- [ydotool](https://github.com/ReimuNotMoe/ydotool), a generic command-line automation tool now has a module. Available as [programs.ydotool](#opt-programs.ydotool.enable).

- [private-gpt](https://github.com/zylon-ai/private-gpt), a service to interact with your documents using the power of LLMs, 100% privately, no data leaks. Available as [services.private-gpt](#opt-services.private-gpt.enable).

## Backward Incompatibilities {#sec-release-24.05-incompatibilities}
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
./programs/xwayland.nix
./programs/yabar.nix
./programs/yazi.nix
./programs/ydotool.nix
./programs/yubikey-touch-detector.nix
./programs/zmap.nix
./programs/zsh/oh-my-zsh.nix
Expand Down
83 changes: 83 additions & 0 deletions nixos/modules/programs/ydotool.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.ydotool;
in
{
meta = {
maintainers = with lib.maintainers; [ quantenzitrone ];
};

options.programs.ydotool = {
enable = lib.mkEnableOption ''
ydotoold system service and install ydotool.
Add yourself to the 'ydotool' group to be able to use it.
'';
};

config = lib.mkIf cfg.enable {
users.groups.ydotool = { };

systemd.services.ydotoold = {
description = "ydotoold - backend for ydotool";
wantedBy = [ "multi-user.target" ];
partOf = [ "multi-user.target" ];
serviceConfig = {
Group = "ydotool";
RuntimeDirectory = "ydotoold";
RuntimeDirectoryMode = "0750";
ExecStart = "${lib.getExe' pkgs.ydotool "ydotoold"} --socket-path=/run/ydotoold/socket --socket-perm=0660";

# hardening

## allow access to uinput
DeviceAllow = [ "/dev/uinput" ];
DevicePolicy = "closed";

## allow creation of unix sockets
RestrictAddressFamilies = [ "AF_UNIX" ];

CapabilityBoundingSet = "";
IPAddressDeny = "any";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateNetwork = true;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
ProtectUser = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0077";

# -> systemd-analyze security score 0.7 SAFE 😀
};
};

environment.variables = {
YDOTOOL_SOCKET = "/run/ydotoold/socket";
};
environment.systemPackages = with pkgs; [ ydotool ];
};
}
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ in {
xterm = handleTest ./xterm.nix {};
xxh = handleTest ./xxh.nix {};
yabar = handleTest ./yabar.nix {};
ydotool = handleTest ./ydotool.nix {};
yggdrasil = handleTest ./yggdrasil.nix {};
zammad = handleTest ./zammad.nix {};
zeronet-conservancy = handleTest ./zeronet-conservancy.nix {};
Expand Down
115 changes: 115 additions & 0 deletions nixos/tests/ydotool.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import ./make-test-python.nix (
{ pkgs, lib, ... }:
let
textInput = "This works.";
inputBoxText = "Enter input";
inputBox = pkgs.writeShellScript "zenity-input" ''
${lib.getExe pkgs.gnome.zenity} --entry --text '${inputBoxText}:' > /tmp/output &
'';
in
{
name = "ydotool";

meta = {
maintainers = with lib.maintainers; [
OPNA2608
quantenzitrone
];
};

nodes = {
headless =
{ config, ... }:
{
imports = [ ./common/user-account.nix ];

users.users.alice.extraGroups = [ "ydotool" ];

programs.ydotool.enable = true;

services.getty.autologinUser = "alice";
};

x11 =
{ config, ... }:
{
imports = [
./common/user-account.nix
./common/auto.nix
./common/x11.nix
];

users.users.alice.extraGroups = [ "ydotool" ];

programs.ydotool.enable = true;

test-support.displayManager.auto = {
enable = true;
user = "alice";
};

services.xserver.windowManager.dwm.enable = true;
services.displayManager.defaultSession = lib.mkForce "none+dwm";
};

wayland =
{ config, ... }:
{
imports = [ ./common/user-account.nix ];

services.cage = {
enable = true;
user = "alice";
};

programs.ydotool.enable = true;

services.cage.program = inputBox;
};
};

enableOCR = true;

testScript =
{ nodes, ... }:
''
def as_user(cmd: str):
"""
Return a shell command for running a shell command as a specific user.
"""
return f"sudo -u alice -i {cmd}"

start_all()

# Headless
headless.wait_for_unit("multi-user.target")
headless.wait_for_text("alice")
headless.succeed(as_user("ydotool type 'echo ${textInput} > /tmp/output'")) # text input
headless.succeed(as_user("ydotool key 28:1 28:0")) # text input
headless.screenshot("headless_input")
headless.wait_for_file("/tmp/output")
headless.wait_until_succeeds("grep '${textInput}' /tmp/output") # text input

# X11
x11.wait_for_x()
x11.execute(as_user("${inputBox}"))
x11.wait_for_text("${inputBoxText}")
x11.succeed(as_user("ydotool type '${textInput}'")) # text input
x11.screenshot("x11_input")
x11.succeed(as_user("ydotool mousemove -a 400 110")) # mouse input
x11.succeed(as_user("ydotool click 0xC0")) # mouse input
x11.wait_for_file("/tmp/output")
x11.wait_until_succeeds("grep '${textInput}' /tmp/output") # text input

# Wayland
wayland.wait_for_unit("graphical.target")
wayland.wait_for_text("${inputBoxText}")
wayland.succeed("ydotool type '${textInput}'") # text input
wayland.screenshot("wayland_input")
wayland.succeed("ydotool mousemove -a 100 100") # mouse input
wayland.succeed("ydotool click 0xC0") # mouse input
wayland.wait_for_file("/tmp/output")
wayland.wait_until_succeeds("grep '${textInput}' /tmp/output") # text input
'';
}
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
{ lib, stdenv, fetchFromGitHub, cmake, scdoc, util-linux, xorg }:
{
lib,
stdenv,
fetchFromGitHub,
cmake,
scdoc,
util-linux,
xorg,
nixosTests,
}:

stdenv.mkDerivation rec {
stdenv.mkDerivation (finalAttrs: {
pname = "ydotool";
version = "1.0.4";

src = fetchFromGitHub {
owner = "ReimuNotMoe";
repo = "ydotool";
rev = "v${version}";
rev = "v${finalAttrs.version}";
hash = "sha256-MtanR+cxz6FsbNBngqLE+ITKPZFHmWGsD1mBDk0OVng=";
};

Expand All @@ -19,13 +28,22 @@ stdenv.mkDerivation rec {
'';

strictDeps = true;
nativeBuildInputs = [ cmake scdoc ];
nativeBuildInputs = [
cmake
scdoc
];

meta = with lib; {
homepage = "https://github.com/ReimuNotMoe/ydotool";
passthru.tests.basic = nixosTests.ydotool;

meta = {
description = "Generic Linux command-line automation tool";
license = licenses.agpl3Plus;
maintainers = with maintainers; [ willibutz kraem ];
platforms = with platforms; linux;
homepage = "https://github.com/ReimuNotMoe/ydotool";
license = lib.licenses.agpl3Plus;
mainProgram = "ydotool";
maintainers = with lib.maintainers; [
willibutz
kraem
];
platforms = lib.platforms.linux;
};
}
})
2 changes: 0 additions & 2 deletions pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4766,8 +4766,6 @@ with pkgs;

wtype = callPackage ../tools/wayland/wtype { };

ydotool = callPackage ../tools/wayland/ydotool { };

cambalache = callPackage ../development/tools/cambalache { };

cambrinary = python3Packages.callPackage ../applications/misc/cambrinary { };
Expand Down