Hey There! I am really enjoying my nixos experience so far! But right now I am stuck trying to repackage a software I regularly use with FHS environments. This is the script I worked out so far:
There are multiple issues with this script, but I cannot figure out how to get it working.
First off, when unpacking the deb, tar complains about being unable to set a sticky bit on chrome-sandbox. Then, when executing the binary in the nix-store it crashes with broken pipes.
The software itself is a launcher which downloads further apps to /opt and executes them. I am wondering what I need to change in order to get a running application in the nix-store. I am relatively new to repackaging binaries, so please feel free to point out if all I have done is crap and point me towards correct ways of implementing this!
So I’ve made some progress. Following is my current derivation:
{
lib,
stdenv,
buildFHSEnvBubblewrap,
fetchurl,
dpkg,
pkgs,
makeWrapper,
wrapGAppsHook,
extraPkgs ? pkgs: [],
}:
stdenv.mkDerivation rec {
pname = "amsel-suite";
version = "1.4.2";
src = fetchurl {
url = "https://github.com/OllamTechnologies/launcher-releases/releases/download/v${version}/amsel-suite_${version}_amd64.deb";
hash = "sha256:d723659cdca890ee5ca15325bf3fd8d0feb346367541e1ca154704699daddc26";
};
nativeBuildInputs = [dpkg wrapGAppsHook makeWrapper];
unpackCmd = ''dpkg -x $curSrc src || true'';
fhsEnv = buildFHSEnvBubblewrap {
pname = "${pname}-fhs-env";
inherit version;
targetPkgs = pkgs: let
sudoShim = pkgs.writeShellScriptBin "sudo" ''
#!/bin/sh
echo "[amsel-fhsenv] sudo shim: running without privileges"
# Führt den Befehl ohne Rechte aus (nur innerhalb des FHS-Env)
exec "$@"
'';
in
with pkgs;
[
glib
gsettings-desktop-schemas
hicolor-icon-theme
nss
nspr
dbus.lib
at-spi2-atk
cups.lib
gtk3
pango
cairo
xorg.libX11
xorg.libXcomposite
xorg.libXdamage
xorg.libXfixes
xorg.libXrandr
libgbm
xorg.libxcb
libxkbcommon
alsa-lib
ffmpeg
libdrm
xorg.libXext
libGL
udev
expat
]
++ extraPkgs pkgs;
# Wrapper, der persistente Ordner anlegt
# erzeuge die Host-Ordner (wird beim Start des wrappers ausgeführt)
extraPreBwrapCmds = ''
mkdir -p "$HOME/.local/share/amsel-suite/opt"
'';
# bwrap-Argumente: binden der Host-Pfade in das FHS-Environment
# $HOME bleibt eine Laufzeit-Variable (wird vom erzeugten Startskript expandiert)
extraBwrapArgs = [
"--bind-try $HOME/.local/share/amsel-suite/opt /opt"
];
runScript = "";
};
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out
mv usr/ $out
makeWrapper ${fhsEnv}/bin/${pname}-fhs-env $out/usr/lib/amsel-suite/amsel-suite \
--add-flags "$out/usr/lib/amsel-suite/Amsel\ Suite" \
"''${gappsWrapperArgs[@]}"
rm $out/usr/bin/amsel-suite
ln -s $out/usr/lib/amsel-suite/amsel-suite $out/usr/bin/amsel-suite
runHook postInstall
'';
meta = with lib; {
description = "Launcher for the Amsel Suite by Ollam Technologies";
homepage = "https://ollam.ai/";
license = licenses.unfree; # falls unklar, unfree setzen
platforms = ["x86_64-linux"];
maintainers = with maintainers; [fstracke];
sourceProvenance = with sourceTypes; [binaryNativeCode];
};
}
However, when the program tries to install downloaded binaries after extraction, it fails returning an error to the user. Has anyone an Idea how I can enable the program to install further binaries especially under /opt?
Okay, so further progress:
I was able to figure out that the binary is using the npm package sudo-prompt (https://www.npmjs.com/package/sudo-prompt?activeTab=code), which internally is trying to run pkexec or kdesudo. I’ll try and create simple wrappers for these programs and see if it works.
Do you have a gist or something to share for those who are trying to packing the amsel suite? I tried by mocking their api before buying it but still can’t make it.
Sorry for the late reply. I haven’t updated my derivation for the new AppImage release since I have not had time yet. This is my current derivation, but fair warning: it is majorly hacky:
{
lib,
stdenv,
buildFHSEnvBubblewrap,
fetchurl,
dpkg,
pkgs,
makeWrapper,
wrapGAppsHook3,
extraPkgs ? pkgs: [],
}:
stdenv.mkDerivation rec {
pname = "amsel-suite";
version = "1.6.3";
src = fetchurl {
url = "https://github.com/OllamTechnologies/launcher-releases/releases/download/v${version}/amsel-suite_${version}_amd64.deb";
hash = "sha256:l2yWGwEiRtf6AmlCrnQmrIhDHfanKwBGhAGjbhlpCbg=";
};
nativeBuildInputs = [dpkg wrapGAppsHook3 makeWrapper];
unpackCmd = ''dpkg -x $curSrc src || true'';
fhsEnv = buildFHSEnvBubblewrap {
pname = "${pname}-fhs-env";
inherit version;
targetPkgs = pkgs: let
pkexecShim = pkgs.writeShellScriptBin "pkexec" ''
#!/bin/sh
echo "[amsel-fhsenv] sudo shim: running without privileges"
# Führt den Befehl ohne Rechte aus (nur innerhalb des FHS-Env)
shift;
exec "$@";
'';
in
with pkgs;
[
pkexecShim
uutils-coreutils-noprefix
glib
gsettings-desktop-schemas
hicolor-icon-theme
nss
nspr
dbus
dbus.lib
at-spi2-atk
cups.lib
gtk3
pango
cairo
libx11
libxcomposite
libxdamage
libxfixes
libxrandr
libgbm
libxcb
libxkbcommon
alsa-lib
ffmpeg
libdrm
libxext
libGL
udev
expat
]
++ extraPkgs pkgs;
# Wrapper, der persistente Ordner anlegt
# erzeuge die Host-Ordner (wird beim Start des wrappers ausgeführt)
extraPreBwrapCmds = ''
mkdir -p "$HOME/.local/share/amsel-suite/opt"
'';
# bwrap-Argumente: binden der Host-Pfade in das FHS-Environment
# $HOME bleibt eine Laufzeit-Variable (wird vom erzeugten Startskript expandiert)
extraBwrapArgs = [
"--bind-try $HOME/.local/share/amsel-suite/opt /opt"
"--bind-try $HOME $HOME"
"--bind-try /tmp/testing /tmp/testing"
];
runScript = "";
profile = ''
export NIXOS_OZONE_WL=1
'';
};
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out
mkdir -p $out/opt
cp -R usr/bin usr/share usr/lib $out/
makeWrapper ${fhsEnv}/bin/${pname}-fhs-env $out/lib/amsel-suite/amsel-suite \
--add-flags "$out/lib/amsel-suite/Amsel\ Suite \''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform=wayland --enable-features=WaylandWindowDecorations}}" \
"''${gappsWrapperArgs[@]}"
rm $out/bin/amsel-suite
ln -s $out/lib/amsel-suite/amsel-suite $out/bin/amsel-suite
runHook postInstall
'';
meta = with lib; {
description = "Launcher for the Amsel Suite by Ollam Technologies";
homepage = "https://www.amsel-suite.com/";
license = licenses.unfree;
platforms = ["x86_64-linux"];
maintainers = with maintainers; [fstracke];
sourceProvenance = with sourceTypes; [binaryNativeCode];
};
}
The gist of it is: Create an /opt in the home dir of the user, which is mounted into the FHS env. The launcher than can install the packages there and read configs from it (such as license keys). Additionally, since they use (or used in that version) an old npm package which relied on pkexec, I made a thin wrapper (which is far from perfect), that just runs the command without sudo privileges. Since the return code is wrong (not equivalent to the one from pkexec) the launcher throws an error, but that can be ignored. Should the UI not update just restart the launcher. Hope this helps!
This is a bad solution. You should use appimageTools (extract and wrapAppImage like example 350) instead of manually unpacking the icon outside Nix and using makeWrapper with appimage-run: