Merge pull request #220761 from elesiuta/picosnitch-init
This commit is contained in:
commit
5d0d352833
6 changed files with 184 additions and 0 deletions
|
@ -4453,6 +4453,12 @@
|
|||
githubId = 103082;
|
||||
name = "Ed Brindley";
|
||||
};
|
||||
elesiuta = {
|
||||
email = "elesiuta@gmail.com";
|
||||
github = "elesiuta";
|
||||
githubId = 8146662;
|
||||
name = "Eric Lesiuta";
|
||||
};
|
||||
eliandoran = {
|
||||
email = "contact@eliandoran.me";
|
||||
name = "Elian Doran";
|
||||
|
|
|
@ -961,6 +961,7 @@
|
|||
./services/networking/pdns-recursor.nix
|
||||
./services/networking/pdnsd.nix
|
||||
./services/networking/peroxide.nix
|
||||
./services/networking/picosnitch.nix
|
||||
./services/networking/pixiecore.nix
|
||||
./services/networking/pleroma.nix
|
||||
./services/networking/polipo.nix
|
||||
|
|
26
nixos/modules/services/networking/picosnitch.nix
Normal file
26
nixos/modules/services/networking/picosnitch.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.picosnitch;
|
||||
in
|
||||
{
|
||||
options.services.picosnitch = {
|
||||
enable = mkEnableOption (lib.mdDoc "picosnitch daemon");
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.picosnitch ];
|
||||
systemd.services.picosnitch = {
|
||||
description = "picosnitch";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
RestartSec = 5;
|
||||
ExecStart = "${pkgs.picosnitch}/bin/picosnitch start-no-daemon";
|
||||
PIDFile = "/run/picosnitch/picosnitch.pid";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
38
pkgs/tools/networking/picosnitch/default.nix
Normal file
38
pkgs/tools/networking/picosnitch/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ lib
|
||||
, python3
|
||||
, bcc
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonApplication rec {
|
||||
pname = "picosnitch";
|
||||
version = "0.12.0";
|
||||
|
||||
src = python3.pkgs.fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "b87654b4b92e28cf5418388ba1d3165b9fa9b17ba91af2a1a942f059128f68bc";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
setuptools
|
||||
bcc
|
||||
psutil
|
||||
dbus-python
|
||||
requests
|
||||
pandas
|
||||
plotly
|
||||
dash
|
||||
];
|
||||
|
||||
patches = [ ./picosnitch.patch ];
|
||||
|
||||
pythonImportsCheck = [ "picosnitch" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Monitor network traffic per executable with hashing";
|
||||
homepage = "https://github.com/elesiuta/picosnitch";
|
||||
changelog = "https://github.com/elesiuta/picosnitch/releases";
|
||||
license = licenses.gpl3Plus;
|
||||
maintainers = [ maintainers.elesiuta ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
111
pkgs/tools/networking/picosnitch/picosnitch.patch
Normal file
111
pkgs/tools/networking/picosnitch/picosnitch.patch
Normal file
|
@ -0,0 +1,111 @@
|
|||
diff --git a/picosnitch.py b/picosnitch.py
|
||||
index a3dbb07..2b74f3e 100755
|
||||
--- a/picosnitch.py
|
||||
+++ b/picosnitch.py
|
||||
@@ -1356,7 +1356,7 @@ def ui_loop(stdscr: curses.window, splash: str, con: sqlite3.Connection) -> int:
|
||||
update_query = False
|
||||
if execute_query:
|
||||
try:
|
||||
- with open("/run/picosnitch.pid", "r") as f:
|
||||
+ with open("/run/picosnitch/picosnitch.pid", "r") as f:
|
||||
run_status = "pid: " + f.read().strip()
|
||||
except Exception:
|
||||
run_status = "not running"
|
||||
@@ -1603,7 +1603,7 @@ def ui_dash():
|
||||
return cmdline
|
||||
def serve_layout():
|
||||
try:
|
||||
- with open("/run/picosnitch.pid", "r") as f:
|
||||
+ with open("/run/picosnitch/picosnitch.pid", "r") as f:
|
||||
run_status = "pid: " + f.read().strip()
|
||||
except Exception:
|
||||
run_status = "not running"
|
||||
@@ -1771,7 +1771,7 @@ def main():
|
||||
# master copy of the snitch dictionary, all subprocesses only receive a static copy of it from this point in time
|
||||
snitch = read_snitch()
|
||||
# start picosnitch process monitor
|
||||
- with open("/run/picosnitch.pid", "r") as f:
|
||||
+ with open("/run/picosnitch/picosnitch.pid", "r") as f:
|
||||
assert int(f.read().strip()) == os.getpid()
|
||||
if __name__ == "__main__" or sys.argv[1] == "start-no-daemon":
|
||||
sys.exit(main_process(snitch))
|
||||
@@ -1818,7 +1818,7 @@ def start_picosnitch():
|
||||
RestartSec=5
|
||||
Environment="SUDO_UID={os.getenv("SUDO_UID")}" "SUDO_USER={os.getenv("SUDO_USER")}" "DBUS_SESSION_BUS_ADDRESS={os.getenv("DBUS_SESSION_BUS_ADDRESS")}" "PYTHON_USER_SITE={site.USER_SITE}"
|
||||
ExecStart={sys.executable} "{os.path.abspath(__file__)}" start-no-daemon
|
||||
- PIDFile=/run/picosnitch.pid
|
||||
+ PIDFile=/run/picosnitch/picosnitch.pid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1832,12 +1832,12 @@ def start_picosnitch():
|
||||
subprocess.Popen(["bash", "-c", f'let i=0; rm {BASE_PATH}/dash; while [[ ! -f {BASE_PATH}/dash || "$i" -gt 30 ]]; do let i++; sleep 1; done; rm {BASE_PATH}/dash && /usr/bin/env python3 -m webbrowser -t http://{os.getenv("HOST", "localhost")}:{os.getenv("PORT", "5100")}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
if os.getuid() != 0:
|
||||
args = ["sudo", "-E", sys.executable, os.path.abspath(__file__), sys.argv[1]]
|
||||
- os.execvp("sudo", args)
|
||||
+ assert sys.argv[1] not in ["start", "stop", "restart", "start-no-daemon"], "picosnitch requires root privileges to run"
|
||||
with open("/proc/self/status", "r") as f:
|
||||
proc_status = f.read()
|
||||
capeff = int(proc_status[proc_status.find("CapEff:")+8:].splitlines()[0].strip(), base=16)
|
||||
cap_sys_admin = 2**21
|
||||
- assert capeff & cap_sys_admin, "Missing capability CAP_SYS_ADMIN"
|
||||
+ assert sys.argv[1] not in ["start", "stop", "restart", "start-no-daemon"] or (capeff & cap_sys_admin), "Missing capability CAP_SYS_ADMIN"
|
||||
assert importlib.util.find_spec("bcc"), "Requires BCC https://github.com/iovisor/bcc/blob/master/INSTALL.md"
|
||||
tmp_snitch = read_snitch()
|
||||
con = sqlite3.connect(os.path.join(BASE_PATH, "snitch.db"))
|
||||
@@ -1883,8 +1883,8 @@ def start_picosnitch():
|
||||
except Exception as e:
|
||||
print("Warning: %s%s on line %s" % (type(e).__name__, str(e.args), sys.exc_info()[2].tb_lineno), file=sys.stderr)
|
||||
if sys.argv[1] in ["start", "stop", "restart"]:
|
||||
- if os.path.exists("/usr/lib/systemd/system/picosnitch.service"):
|
||||
- print("Found /usr/lib/systemd/system/picosnitch.service but you are not using systemctl")
|
||||
+ if os.path.exists("/usr/lib/systemd/system/picosnitch.service") or os.path.exists("/etc/systemd/system/picosnitch.service"):
|
||||
+ print("Found picosnitch.service but you are not using systemctl")
|
||||
if sys.stdin.isatty():
|
||||
confirm = input(f"Did you intend to run `systemctl {sys.argv[1]} picosnitch` (y/N)? ")
|
||||
if confirm.lower().startswith("y"):
|
||||
@@ -1893,15 +1893,15 @@ def start_picosnitch():
|
||||
class PicoDaemon(Daemon):
|
||||
def run(self):
|
||||
main()
|
||||
- daemon = PicoDaemon("/run/picosnitch.pid")
|
||||
+ daemon = PicoDaemon("/run/picosnitch/picosnitch.pid")
|
||||
if sys.argv[1] == "start":
|
||||
- print("starting picosnitch daemon")
|
||||
+ print("starting picosnitch daemon, WARNING: built in daemon mode is not supported on Nix, use picosnitch start-no-daemon or systemctl instead")
|
||||
daemon.start()
|
||||
elif sys.argv[1] == "stop":
|
||||
- print("stopping picosnitch daemon")
|
||||
+ print("stopping picosnitch daemon, WARNING: built in daemon mode is not supported on Nix, use picosnitch start-no-daemon or systemctl instead")
|
||||
daemon.stop()
|
||||
elif sys.argv[1] == "restart":
|
||||
- print("restarting picosnitch daemon")
|
||||
+ print("restarting picosnitch daemon, WARNING: built in daemon mode is not supported on Nix, use picosnitch start-no-daemon or systemctl instead")
|
||||
daemon.restart()
|
||||
elif sys.argv[1] == "status":
|
||||
daemon.status()
|
||||
@@ -1912,11 +1912,12 @@ def start_picosnitch():
|
||||
print("Wrote /usr/lib/systemd/system/picosnitch.service\nYou can now run picosnitch using systemctl")
|
||||
return 0
|
||||
elif sys.argv[1] == "start-no-daemon":
|
||||
- assert not os.path.exists("/run/picosnitch.pid")
|
||||
+ assert not os.path.exists("/run/picosnitch/picosnitch.pid")
|
||||
def delpid():
|
||||
- os.remove("/run/picosnitch.pid")
|
||||
+ os.remove("/run/picosnitch/picosnitch.pid")
|
||||
atexit.register(delpid)
|
||||
- with open("/run/picosnitch.pid", "w") as f:
|
||||
+ os.makedirs("/run/picosnitch", exist_ok=True)
|
||||
+ with open("/run/picosnitch/picosnitch.pid", "w") as f:
|
||||
f.write(str(os.getpid()) + "\n")
|
||||
print("starting picosnitch in simple mode")
|
||||
print(f"using config and log files from: {BASE_PATH}")
|
||||
@@ -1927,7 +1928,7 @@ def start_picosnitch():
|
||||
assert dash.__version__ and pandas.__version__ and plotly.__version__
|
||||
print(f"serving web gui on http://{os.getenv('HOST', 'localhost')}:{os.getenv('PORT', '5100')}")
|
||||
args = ["bash", "-c", f"sudo -i -u {os.getenv('SUDO_USER')} touch {BASE_PATH}/dash; nohup {sys.executable} \"{os.path.abspath(__file__)}\" start-dash > /dev/null 2>&1 &"]
|
||||
- os.execvp("bash", args)
|
||||
+ return ui_dash()
|
||||
elif sys.argv[1] == "start-dash":
|
||||
return ui_dash()
|
||||
elif sys.argv[1] == "view":
|
|
@ -33097,6 +33097,8 @@ with pkgs;
|
|||
|
||||
picoloop = callPackage ../applications/audio/picoloop { };
|
||||
|
||||
picosnitch = callPackage ../tools/networking/picosnitch { };
|
||||
|
||||
pidgin = callPackage ../applications/networking/instant-messengers/pidgin {
|
||||
withOpenssl = config.pidgin.openssl or true;
|
||||
withGnutls = config.pidgin.gnutls or false;
|
||||
|
|
Loading…
Reference in a new issue