From a0c199ba06e86281cade6c35b7f33938c30d2177 Mon Sep 17 00:00:00 2001 From: Zuckerberg Date: Wed, 8 Feb 2023 01:38:54 -0500 Subject: [PATCH] Unfinished attempt at packaging pia client --- common/pc/pia/default.nix | 76 +++++++++++++++++++ common/pc/pia/fix-pia.patch | 147 ++++++++++++++++++++++++++++++++++++ common/pc/pia/pia.nix | 139 ++++++++++++++++++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 common/pc/pia/default.nix create mode 100644 common/pc/pia/fix-pia.patch create mode 100644 common/pc/pia/pia.nix diff --git a/common/pc/pia/default.nix b/common/pc/pia/default.nix new file mode 100644 index 0000000..20cb3cf --- /dev/null +++ b/common/pc/pia/default.nix @@ -0,0 +1,76 @@ +{ lib, config, pkgs, ... }: + +with lib; + +let + cfg = config.services.pia; +in { + imports = [ + ./pia.nix + ]; + + options.services.pia = { + enable = lib.mkEnableOption "Enable PIA Client"; + + dataDir = lib.mkOption { + type = lib.types.str; + default = "/var/lib/pia"; + description = '' + Path to the pia data directory + ''; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "root"; + description = '' + The user pia should run as + ''; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "piagrp"; + description = '' + The group pia should run as + ''; + }; + + users = mkOption { + type = with types; listOf str; + default = []; + description = '' + Usernames to be added to the "spotifyd" group, so that they + can start and interact with the userspace daemon. + ''; + }; + }; + + config = mkIf cfg.enable { + + # users.users.${cfg.user} = + # if cfg.user == "pia" then { + # isSystemUser = true; + # group = cfg.group; + # home = cfg.dataDir; + # createHome = true; + # } + # else {}; + users.groups.${cfg.group}.members = cfg.users; + + systemd.services.pia-daemon = { + enable = true; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = "${pkgs.pia-daemon}/bin/pia-daemon"; + serviceConfig.PrivateTmp="yes"; + serviceConfig.User = cfg.user; + serviceConfig.Group = cfg.group; + preStart = '' + mkdir -p ${cfg.dataDir} + chown ${cfg.user}:${cfg.group} ${cfg.dataDir} + ''; + }; + + }; +} \ No newline at end of file diff --git a/common/pc/pia/fix-pia.patch b/common/pc/pia/fix-pia.patch new file mode 100644 index 0000000..b6f474e --- /dev/null +++ b/common/pc/pia/fix-pia.patch @@ -0,0 +1,147 @@ +diff --git a/Rakefile b/Rakefile +index fa6d771..bcd6fb1 100644 +--- a/Rakefile ++++ b/Rakefile +@@ -151,41 +151,6 @@ end + # Install LICENSE.txt + stage.install('LICENSE.txt', :res) + +-# Download server lists to ship preloaded copies with the app. These tasks +-# depend on version.txt so they're refreshed periodically (whenver a new commit +-# is made), but not for every build. +-# +-# SERVER_DATA_DIR can be set to use existing files instead of downloading them; +-# this is primarily intended for reproducing a build. +-# +-# Create a probe for SERVER_DATA_DIR so these are updated if it changes. +-serverDataProbe = Probe.new('serverdata') +-serverDataProbe.file('serverdata.txt', "#{ENV['SERVER_DATA_DIR']}") +-# JSON resource build directory +-jsonFetched = Build.new('json-fetched') +-# These are the assets we need to fetch and the URIs we get them from +-{ +- 'modern_shadowsocks.json': 'https://serverlist.piaservers.net/shadow_socks', +- 'modern_servers.json': 'https://serverlist.piaservers.net/vpninfo/servers/v6', +- 'modern_region_meta.json': 'https://serverlist.piaservers.net/vpninfo/regions/v2' +-}.each do |k, v| +- fetchedFile = jsonFetched.artifact(k.to_s) +- serverDataDir = ENV['SERVER_DATA_DIR'] +- file fetchedFile => [version.artifact('version.txt'), +- serverDataProbe.artifact('serverdata.txt'), +- jsonFetched.componentDir] do |t| +- if(serverDataDir) +- # Use the copy provided instead of fetching (for reproducing a build) +- File.copy(File.join(serverDataDir, k), fetchedFile) +- else +- # Fetch from the web API (write with "binary" mode so LF is not +- # converted to CRLF on Windows) +- File.binwrite(t.name, Net::HTTP.get(URI(v))) +- end +- end +- stage.install(fetchedFile, :res) +-end +- + # Install version/brand/arch info in case an upgrade needs to know what is + # currently installed + stage.install(version.artifact('version.txt'), :res) +diff --git a/common/src/posix/unixsignalhandler.cpp b/common/src/posix/unixsignalhandler.cpp +index f820a6d..e1b6c33 100644 +--- a/common/src/posix/unixsignalhandler.cpp ++++ b/common/src/posix/unixsignalhandler.cpp +@@ -132,7 +132,7 @@ void UnixSignalHandler::_signalHandler(int, siginfo_t *info, void *) + // we checked it, we can't even log because the logger is not reentrant. + auto pThis = instance(); + if(pThis) +- ::write(pThis->_sigFd[0], info, sizeof(siginfo_t)); ++ auto _ = ::write(pThis->_sigFd[0], info, sizeof(siginfo_t)); + } + template + void UnixSignalHandler::setAbortAction() +diff --git a/daemon/src/linux/linux_nl.cpp b/daemon/src/linux/linux_nl.cpp +index fd3aced..2367a5e 100644 +--- a/daemon/src/linux/linux_nl.cpp ++++ b/daemon/src/linux/linux_nl.cpp +@@ -642,6 +642,6 @@ LinuxNl::~LinuxNl() + unsigned char term = 0; + PosixFd killSocket = _workerKillSocket.get(); + if(killSocket) +- ::write(killSocket.get(), &term, sizeof(term)); ++ auto _ = ::write(killSocket.get(), &term, sizeof(term)); + _workerThread.join(); + } +diff --git a/extras/support-tool/launcher/linux-launcher.cpp b/extras/support-tool/launcher/linux-launcher.cpp +index 3f63ac2..420d54d 100644 +--- a/extras/support-tool/launcher/linux-launcher.cpp ++++ b/extras/support-tool/launcher/linux-launcher.cpp +@@ -48,7 +48,7 @@ int fork_execv(gid_t gid, char *filename, char *const argv[]) + if(forkResult == 0) + { + // Apply gid as both real and effective +- setregid(gid, gid); ++ auto _ = setregid(gid, gid); + + int execErr = execv(filename, argv); + std::cerr << "exec err: " << execErr << " / " << errno << " - " +diff --git a/rake/model/qt.rb b/rake/model/qt.rb +index c8cd362..a6abe59 100644 +--- a/rake/model/qt.rb ++++ b/rake/model/qt.rb +@@ -171,12 +171,7 @@ class Qt + end + + def getQtRoot(qtVersion, arch) +- qtToolchainPtns = getQtToolchainPatterns(arch) +- qtRoots = FileList[*Util.joinPaths([[qtVersion], qtToolchainPtns])] +- # Explicitly filter for existing paths - if the pattern has wildcards +- # we only get existing directories, but if the patterns are just +- # alternates with no wildcards, we can get directories that don't exist +- qtRoots.find_all { |r| File.exist?(r) }.max ++ ENV['QTROOT'] + end + + def getQtVersionScore(minor, patch) +@@ -192,12 +187,7 @@ class Qt + end + + def getQtPathVersion(path) +- verMatch = path.match('^.*/Qt[^/]*/5\.(\d+)\.?(\d*)$') +- if(verMatch == nil) +- nil +- else +- [verMatch[1].to_i, verMatch[2].to_i] +- end ++ [ENV['QT_MAJOR'].to_i, ENV['QT_MINOR'].to_i] + end + + # Build a component definition with the defaults. The "Core" component will +diff --git a/rake/product/linux.rb b/rake/product/linux.rb +index f43fb3e..83505af 100644 +--- a/rake/product/linux.rb ++++ b/rake/product/linux.rb +@@ -18,8 +18,7 @@ module PiaLinux + QT_BINARIES = %w(pia-client pia-daemon piactl pia-support-tool) + + # Version of libicu (needed to determine lib*.so.## file names in deployment) +- ICU_VERSION = FileList[File.join(Executable::Qt.targetQtRoot, 'lib', 'libicudata.so.*')] +- .first.match(/libicudata\.so\.(\d+)(\..*|)/)[1] ++ ICU_VERSION = ENV['ICU_MAJOR'].to_i; + + # Copy a directory recursively, excluding *.debug files (debugging symbols) + def self.copyWithoutDebug(sourceDir, destDir) +@@ -220,16 +219,5 @@ module PiaLinux + # Since these are just development workflow tools, they can be skipped if + # specific dependencies are not available. + def self.defineTools(toolsStage) +- # Test if we have libthai-dev, for the Thai word breaking utility +- if(Executable::Tc.sysHeaderAvailable?('thai/thwbrk.h')) +- Executable.new('thaibreak') +- .source('tools/thaibreak') +- .lib('thai') +- .install(toolsStage, :bin) +- toolsStage.install('tools/thaibreak/thai_ts.sh', :bin) +- toolsStage.install('tools/onesky_import/import_translations.sh', :bin) +- else +- puts "skipping thaibreak utility, install libthai-dev to build thaibreak" +- end + end + end diff --git a/common/pc/pia/pia.nix b/common/pc/pia/pia.nix new file mode 100644 index 0000000..67f9837 --- /dev/null +++ b/common/pc/pia/pia.nix @@ -0,0 +1,139 @@ +{ pkgs, lib, config, ... }: + +{ + nixpkgs.overlays = [ + (self: super: + + with self; + + let + # arch = builtins.elemAt (lib.strings.splitString "-" builtins.currentSystem) 0; + arch = "x86_64"; + + pia-desktop = clangStdenv.mkDerivation rec { + pname = "pia-desktop"; + version = "3.3.0"; + + src = fetchgit { + url = "https://github.com/pia-foss/desktop"; + rev = version; + fetchLFS = true; + sha256 = "D9txL5MUWyRYTnsnhlQdYT4dGVpj8PFsVa5hkrb36cw="; + }; + + patches = [ + ./fix-pia.patch + ]; + + nativeBuildInputs = [ + cmake + rake + ]; + + prePatch = '' + sed -i 's|/usr/include/libnl3|${libnl.dev}/include/libnl3|' Rakefile + ''; + + installPhase = '' + mkdir -p $out/bin $out/lib $out/share + cp -r ../out/pia_release_${arch}/stage/bin $out + cp -r ../out/pia_release_${arch}/stage/lib $out + cp -r ../out/pia_release_${arch}/stage/share $out + ''; + + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Release" + ]; + + QTROOT = "${qt5.full}"; + QT_MAJOR = lib.versions.minor (lib.strings.parseDrvName qt5.full.name).version; + QT_MINOR = lib.versions.patch (lib.strings.parseDrvName qt5.full.name).version; + ICU_MAJOR = lib.versions.major (lib.strings.parseDrvName icu.name).version; + + buildInputs = [ + mesa + libsForQt5.qt5.qtquickcontrols + libsForQt5.qt5.qtquickcontrols2 + icu + libnl + ]; + + dontWrapQtApps = true; + }; + in rec { + openvpn-updown = buildFHSUserEnv { + name = "openvpn-updown"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "openvpn-updown.sh"; + }; + + pia-client = buildFHSUserEnv { + name = "pia-client"; + targetPkgs = pkgs: (with pkgs; [ + pia-desktop + xorg.libXau + xorg.libXdmcp + ]); + runScript = "pia-client"; + }; + + piactl = buildFHSUserEnv { + name = "piactl"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "piactl"; + }; + + pia-daemon = buildFHSUserEnv { + name = "pia-daemon"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-daemon"; + }; + + pia-hnsd = buildFHSUserEnv { + name = "pia-hnsd"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-hnsd"; + }; + + pia-openvpn = buildFHSUserEnv { + name = "pia-openvpn"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-openvpn"; + }; + + pia-ss-local = buildFHSUserEnv { + name = "pia-ss-local"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-ss-local"; + }; + + pia-support-tool = buildFHSUserEnv { + name = "pia-support-tool"; + targetPkgs = pkgs: (with pkgs; [ + pia-desktop + xorg.libXau + xorg.libXdmcp + ]); + runScript = "pia-support-tool"; + }; + + pia-unbound = buildFHSUserEnv { + name = "pia-unbound"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-unbound"; + }; + + pia-wireguard-go = buildFHSUserEnv { + name = "pia-wireguard-go"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "pia-wireguard-go"; + }; + + support-tool-launcher = buildFHSUserEnv { + name = "support-tool-launcher"; + targetPkgs = pkgs: (with pkgs; [ pia-desktop ]); + runScript = "support-tool-launcher"; + }; + }) + ]; +} \ No newline at end of file