How to use custom python with existing packages - nix derivation? - nix

I defined a custom nix cpython derivation with unmerged patches. If I specify it as a target nix-shell gives me the version I expect.
{ pkgs ? import <nixpkgs> {} }:
(pkgs.python3.overrideAttrs (old: {
src = pkgs.fetchFromGitHub {
owner = "bergkvist";
repo = "cpython";
rev = "01bcf2bef5f4ffffb454da35cb66b186a7a12598";
sha256 = "1713sx5izd745bgr6fdx6d1g7ivaqy6jrf9v5jgml31bd1nmfccy";
};
verions = "3.11.5";
})) })).override {
sourceVersion = {major = "3"; minor = "11" ; patch = "5"; suffix = ""; };
};
$ nix-shell
$ python
Python 3.11.0a0 (default, Aug 4 2021, 00:12:31) [Clang 7.1.0 (tags/RELEASE_710/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
But I don't see a way how to use new cpython for existing packages.
Straight forward overlay doesn't affect anything.
{ pkgs ? import <nixpkgs> {} }:
let myPatchedPython = ... ;
myPkgs = pkgs.extend(self: super: {
python3 = myPatchedPython;
python39 = myPatchedPython;
});
in myPkgs.python39Packages.send2trash
$ nix-shell
$ python3
Python 3.9.5 (default, Jul 18 2021, 14:31:15)
I noticed I can use override but it is only for runtime and it is not working for all packages.
let useMyPy = drv: drv.override {
python = myPatchedPython;
python3 = myPatchedPython;
python38 = myPatchedPython;
python39 = myPatchedPython;
};
pyobjc-core = useMyPy (pkgs.python39Packages.buildPythonPackage rec {
pname = "pyobjc-core";
version = "7.3";
adfasdf = true;
name = "${pname}-${version}";
src = pkgs.python39Packages.fetchPypi {
pname = "pyobjc-core";
inherit version;
sha256 = "0x3msrzvcszlmladdpl64s48l52fwk4xlnnri8daq2mliggsx0ah";
};
propagatedBuildInputs = [
myPatchedPython
pkgs.darwin.libobjc
pkgs.darwin.cctools
pkgs.darwin.apple_sdk.frameworks.Foundation
pkgs.darwin.apple_sdk.frameworks.AppKit
pkgs.darwin.apple_sdk.frameworks.CoreServices
pkgs.darwin.apple_sdk.frameworks.Cocoa
pkgs.python39Packages.setuptools
];
buildInputs = [ pkgs.libffi ];
});
in pyobjc-core
$ nix-shell
$ python3
Python 3.11.0a0 (default, Aug 4 2021, 00:12:31) [Clang 7.1.0 (tags/RELEASE_710/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import import AppKit
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/nix/store/jcc0xf3zwxnzzh497nip7v57k68r4zb9-python3.9-pyobjc-7.3/lib/python3.9/site-packages/AppKit/__init__.py", line 10, in <module>
import Foundation
^^^^^^^^^^^^^^^^^
...

AFAIK, the official way to do this is to define myPatchedPython in an overlay for nixpkgs (in ~/.config/nixpkgs/overlays.nix), and invoke nix-shell like so:
nix-shell -p myPatchedPython
If this does not work, you can also try nix-shell -E '(import <nixpkgs> {}).myPatchedPython' and the like, which give you more of a debugging angle.
The more pedantic way (without overlays) that I have used in the past with success is to directly copy or include your patched Python version in the shell.nix file, e.g.:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
pkgs.python.overrideAttrs { ... }
];
}

Related

Nix Flake get a specific python version

I am trying to make a Nix flake which will use poetry2nix for building a poetry project the code is
{
description = "searx : flake";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;
outputs = { self, nixpkgs }: {
defaultPackage.x86_64-linux =
with import nixpkgs { system = "x86_64-linux";
buildInputs = [
nixpkgs.python39
nixpkgs.git
nixpkgs.openssl
nixpkgs.python39Packages.pip
nixpkgs.uwsgi
nixpkgs.python39Packages.virtualenv
nixpkgs.poetry
];
};
pkgs.poetry2nix.mkPoetryApplication {
projectDir = ./.;
src = pkgs.fetchgit {
url = "https://github.com/searx/searx.git";
rev = "ae122ea943f77600fd97556503c483dcd92e1e63";
sha256 = "sIJ+QXwUdsRIpg6ffUS3ItQvrFy0kmtI8whaiR7qEz4=";
};
};
};
However the Nix flake starts pulling python3.7 and breaks with following error
ERROR: Could not find a version that satisfies the requirement importlib-metadata; python_version < "3.8" (from click==8.0.1) (from versions: none)
> ERROR: No matching distribution found for importlib-metadata; python_version < "3.8" (from click==8.0.1)
Equivalent default.nix pulls python 3.9 and builds successfully. I believe if flake could be pinned to python3.9 it will be able to build this. Is this possible?
You can pass another python to mkPoetryApplication.
pkgs.poetry2nix.mkPoetryApplication {
projectDir = ./.;
python = pkgs.python39;
# ... your code ...
}

How to specify multiple packages/derivation for installation by nix-env?

I have a single file (dep-terraform.nix) with contents of:
{ sources ? import ./nix/sources.nix
} :
let
niv = import sources.nixpkgs {
overlays = [
(_ : _ : { niv = import sources.niv {}; })
] ;
config = {};
};
pkgs = niv.pkgs;
in
pkgs.terraform.withPlugins(p: [p.google])
The above (a single package/derivation) can successfully be installed with nix-env -if dep-terraform.nix. How can specify additional packages to be installed using the above approach (without having to create a file for each dependency)?
It is possible to install list of packages using nix-env:
$ echo 'with import <nixpkgs>{}; [ htop moreutils ]' > /tmp/tmp.nix
$ nix-env -if /tmp/tmp.nix
installing 'htop-2.2.0'
installing 'moreutils-0.63'
building '/nix/store/dvhlfnmjska9j55jr4m6cch7xwdgf59a-user-environment.drv'...
created 1419 symlinks in user environment

How can I enable Caddy plugins in NixOS?

I've just started playing with NixOS, and have so far managed to edit /etc/nixos/configuration.nix in my NixOS 18.09 VM to have PHP-FPM and the Caddy webserver enabled.
{ config, pkgs, ... }:
{
imports = [ <nixpkgs/nixos/modules/installer/virtualbox-demo.nix> ];
users = {
mutableUsers = false;
groups = {
caddy = { };
php-project = { };
};
users = {
hello = {
group = "php-project";
};
};
};
environment.systemPackages = [
pkgs.htop
pkgs.httpie
pkgs.php # for PHP CLI
];
services.caddy = {
enable = true;
email = "david#example.com";
agree = true;
config = ''
(common) {
gzip
header / -Server
header / -X-Powered-By
}
:8080 {
root /var/www/hello
fastcgi / /run/phpfpm/hello.sock php
log syslog
import common
}
'';
};
services.phpfpm = {
phpOptions = ''
date.timezone = "Europe/Berlin"
'';
poolConfigs = {
hello = ''
user = hello
listen = /run/phpfpm/hello.sock
; ...
pm.max_requests = 500
'';
};
};
}
A PHP-processed response is available at at localhost:8080. (Yay!)
To enable Caddy plugins when compiling from source, Go imports are added to caddy's run.go, e.g.:
_ "github.com/mholt/caddy/caddyhttp" // plug in the HTTP server type
// This is where other plugins get plugged in (imported)
_ "github.com/nicolasazrak/caddy-cache" // added to use another plugin
)
How can I set such line insertion to be performed after the source is downloaded and before the build takes place? (If this is a reasonable approach when using Nix?)
The NixOS 18.09 caddy package.
The NixOS 18.09 caddy service.
I believe that when writing a package a builder script (Bash or otherwise) can be assigned, and I'm thinking the line insertion could be done in it. But I'm lost as to how to assign a script to an existing package in this situation (override an attribute/use an overlay?) and where to put the script on the disk.
Status update
I've been doing some reading on customising packages in general and it sounds like overlays might be what I need. However, I don't seem to be able to get my overlay evaluated.
I'm using overriding of the package name as a test as it's simpler than patching code.
Overlay attempt 1
/etc/nixos/configuration.nix:
{ config, pkgs, options, ... }:
{
imports = [ <nixpkgs/nixos/modules/installer/virtualbox-demo.nix> ];
nix.nixPath = options.nix.nixPath.default ++ [
"nixpkgs-overlays=/etc/nixos/overlays-compat/"
];
# ...
}
/etc/nixos/overlays-compat/overlays.nix:
self: super:
with super.lib;
let
# Using the nixos plumbing that's used to evaluate the config...
eval = import <nixpkgs/nixos/lib/eval-config.nix>;
# Evaluate the config,
paths = (eval {modules = [(import <nixos-config>)];})
# then get the `nixpkgs.overlays` option.
.config.nixpkgs.overlays
;
in
foldl' (flip extends) (_: super) paths self
/etc/nixos/overlays-compat/caddy.nix:
self: super:
{
caddy = super.caddy.override {
name = "caddy-override";
};
}
Overlay attempt 2
/etc/nixos/configuration.nix:
nixpkgs.overlays = [ (self: super: {
caddy = super.caddy.override {
name = "caddy-override";
};
} ) ];
error: anonymous function at /nix/store/mr5sfmz6lm5952ch5q6v49563wzylrkx-nixos-18.09.2327.37694c8cc0e/nixos/pkgs/servers/caddy/default.nix:1:1 called with unexpected argument 'name', at /nix/store/mr5sfmz6lm5952ch5q6v49563wzylrkx-nixos-18.09.2327.37694c8cc0e/nixos/lib/customisation.nix:69:12
overrideAttrs
I previously managed to override the package name with this:
{ config, pkgs, options, ... }:
let
caddyOverride = pkgs.caddy.overrideAttrs (oldAttrs: rec {
name = "caddy-override-v${oldAttrs.version}";
});
in {
{
# ...
services.caddy = {
package = caddyOverride;
# ...
}
}
I could see in htop that the caddy binary was in a folder called /nix/store/...-caddy-override-v0.11.0-bin/. But I understand that overriding in this way has been superseded by overlays.
In order to add plugins to Caddy, it seems that the method is to modify the source.
You will need to adapt the Nixpkgs expression for Caddy to make that possible. That can be done outside the Nixpkgs tree, using services.caddy.package = callPackage ./my-caddy.nix {} for example, or by forking the Nixpkgs repository and pointing your NIX_PATH to your clone.
There is an issue for Caddy plugins: https://github.com/NixOS/nixpkgs/issues/14671
PR welcome!

NixOS: Install unfree package using different channel

I am using the default nixos 17.09 channel and want to install an unfree package from the unstable channel.
I am using (import <nixos-unstable> {}).vscode to install vscode in this case, but I am getting the error that I must set ...allowUnfree = true;
It seems that the setting only applies to the default channel.
How can I set allowFree = true; also on the unstable channel?
I found a solution (https://github.com/NixOS/nixpkgs/issues/25880#issuecomment-322855573).
It creates an alias for the unstable channel with the same config.
nixpkgs.config =
{
# Allow proprietary packages
allowUnfree = true;
# Create an alias for the unstable channel
packageOverrides = pkgs:
{
unstable = import <nixos-unstable>
{
# pass the nixpkgs config to the unstable alias
# to ensure `allowUnfree = true;` is propagated:
config = config.nixpkgs.config;
};
};
};
Then you can use it like unstable.vscode instead of (import <nixos-unstable> {}).vscode.
As an alternative example:
{ config, pkgs, ... }:
let
unstable = import <unstable> {
config = config.nixpkgs.config;
};
in
{
environment.systemPackages = with pkgs; [
# google-chrome
unstable.google-chrome
];
nixpkgs.config.allowUnfree = true;
}

How to include static data files into luarock?

This is my first time creating a luarock and writing .rockpec file. I have a small lua script and some static text files that this script requires to use. How should I pack my luarock so that these static files are available for my script?
For example, here is my myscript.rockspeck file:
package = "myscript"
version = "1.0-1"
source = {
url = "https://github.com/me/myscript/raw/master/myscript-1.0.tar.gz",
tag = "v1.0"
}
description = {
summary = "My script.",
detailed = [[
Some lua script.
]],
homepage = "https://github.com/me/myscript",
license = "MIT"
}
dependencies = {
"lua >= 5.1, < 5.4"
}
build = {
type = "builtin",
modules = {
myfun = "src/myscript.lua"
},
copy_directories = {"my_data"}
}
I am able to do :
luarocks pack myscript-1.0-1.rockspec
sudo luarocks install myscript-1.0-1.src.rock
However, upon importing myfun module I can see that the my_data directory with the required files inside is not accessible by the module as it complains accordingly.
When I do laurocks pack my working directory contains myscript-1.0.tar.gz with the following sctructure:
myscript-1.0/
src/myscript.lua
tiny_data/
data1.txt
data2.txt
How should I correctly include my_data static files?

Resources