NixOS: Install a non-nix package? - linux

Currently I started using NixOS, and it's working great except for that there are some packages I want to install that are not in the repository.
The first package I had issues with is Cryptomator (https://cryptomator.org)
What I tried to do is follow this tutorial: http://anderspapitto.com/posts/2015-02-28-deb-installation-nixos.html
But I couldn't get it to work... Here is what I tried:
First I created 3 files (as in the tutorial):
builder.sh (as-is from tutorial)
fhs-env.nix (also as-is)
full-cryptomator.nix (source listed below)
dumb-cryptomator.nix (source listed below)
full-cryptomator.nix
let nixpkgs = import <nixpkgs> {};
stdenv = nixpkgs.stdenv;
in rec {
dumb-cryptomator = stdenv.mkDerivation {
name = "dumb-cryptomator";
builder = ./builder.sh;
dpkg = nixpkgs.dpkg;
src = nixpkgs.fetchurl {
url = "https://bintray.com/cryptomator/cryptomator-deb/download_file?file_path=cryptomator-1.2.3-amd64.deb";
sha256 = "f611dfd77f68ddd4b7322b1668829add987c5f8e0fcd639211b46969f1eb8ef3";
};
};
full-cryptomator = nixpkgs.buildFHSUserEnv {
name = "full-cryptomator";
targetPkgs = pkgs: [ dumb-cryptomator ];
multiPkgs = pkgs: [ pkgs.dpkg ];
runScript = "Cryptomator";
};
}
dumb-cryptomator.nix
let nixpkgs = import <nixpkgs> {};
stdenv = nixpkgs.stdenv;
in rec {
dumb-cryptomator = stdenv.mkDerivation {
name = "dumb-cryptomator";
builder = ./builder.sh;
dpkg = nixpkgs.dpkg;
src = nixpkgs.fetchurl {
url = "https://bintray.com/cryptomator/cryptomator-deb/download_file?file_path=cryptomator-1.2.3-amd64.deb";
sha256 = "f611dfd77f68ddd4b7322b1668829add987c5f8e0fcd639211b46969f1eb8ef3";
};
};
}
I then run:
nix-build -A fhsEnv fhs-env.nix
nix-build -A dumb-cryptomator dumb-cryptomator.nix
nix-build -A full-cryptomator full-cryptomator.nix
When the last build is completed, I don't have a full cryptomator install in my directory (at least /opt/Cryptomator should be there):
[peter#peter-laptop:~/Downloads/cryptomator]$ ls /nix/store/6prdbjgidgqaqfnvmkrhnj8xp28z8dxw-full-cryptomator
bin
Is there anyone having more experience with making third-party packages work? Thanks!

At least you should change
runScript = "Cryptomator";
to
runScript = "${dumb-cryptomator}/Cryptomator/Cryptomator";
Debugging such kinds of problems is easy. When you run nix-build -A full-cryptomator full-cryptomator.nix, a symlink result is created, so you can access application by
$ ./result/bin/full-cryptomator
/nix/store/7nc1j85m67kjd1y1fnk6xg5b7w7a1jjd-full-cryptomator-init: line 11: exec: Cryptomator: not found
Whoops! Why's that? let's look into mentioned file:
$ cat /nix/store/7nc1j85m67kjd1y1fnk6xg5b7w7a1jjd-full-cryptomator-init
#! /nix/store/wsz11sx18n85if6gp50m870rypgavwpd-bash-4.4-p12/bin/bash
for i in /nix/store/ss4j5rr2ilh878m1g5c76njcmvmrszja-full-cryptomator-fhs/* /host/*; do
path="/${i##*/}"
[ -e "$path" ] || /nix/store/sxzm5kva1gb0hxm60xvr45m3c5l84xlz-coreutils-8.27/bin/ln -s "$i" "$path"
done
[ -d "$1" ] && [ -r "$1" ] && cd "$1"
shift
source /etc/profile
exec Cryptomator "$#"
Looks like it can't file Cryptomator executable in current PATH. When we inspect actual dumb-cryptomator, we see
$ tree /nix/store/m31pyd1hgpa9v8gnxrjijd1v3n8vxggj-dumb-cryptomator | grep -i crypto
/nix/store/m31pyd1hgpa9v8gnxrjijd1v3n8vxggj-dumb-cryptomator
└── Cryptomator
│   ├── cryptolib-1.0.7.jar
│   ├── Cryptomator-1.2.3.jar
│   ├── Cryptomator.cfg
│   ├── filesystem-crypto-1.2.3.jar
├── Cryptomator
├── Cryptomator.desktop
├── cryptomator.org-Cryptomator-MimeInfo.xml
├── Cryptomator.png
So, it doesn't belong to standard bin folder. As we don't want to mess with package alot, we provide a full path, by using ${dumb-cryptomator} string interpolation.
(that's one of the most used features in Nix, ${dumb-cryptomator} gets expanded to /nix/store/m31pyd1hgpa9v8gnxrjijd1v3n8vxggj-dumb-cryptomator during builds)

Related

Setting up html report with Jasmine

I'm new to BDD and Jasmine, and I'm not able to configure https://www.npmjs.com/package/jasmine-pretty-html-reporter to get html of test pass rate.
There it mentions a basic setup:
var Jasmine = require('jasmine');
var HtmlReporter = require('jasmine-pretty-html-reporter').Reporter;
var jasmine = new Jasmine();
jasmine.loadConfigFile('./spec/support/jasmine.json');
// options object
jasmine.addReporter(new HtmlReporter({
path: path.join(__dirname,'results')
}));
jasmine.execute();
However, I'm not sure where should I perform those configuration (in which file).
Could anyone help me with this, please?
Thanks in advance!
The setup provided by this package is used jasmine as a library. See Using the library.
This means we can execute test cases programmatically. We execute this module via node, e.g.
Folder structure:
⚡ tree -L 2 -I 'node_modules'
.
├── README.md
├── jasmine.json
├── package-lock.json
├── package.json
├── src
│ ├── helpers
│ └── stackoverflow
├── test-reporter
│ └── report.html
└── tsconfig.json
4 directories, 6 files
src/stackoverflow/70338811/as-a-library.js:
var Jasmine = require('jasmine');
var path = require('path');
var HtmlReporter = require('jasmine-pretty-html-reporter').Reporter;
var jasmine = new Jasmine();
jasmine.loadConfigFile(path.resolve(__dirname, '../../../jasmine.json'));
jasmine.addReporter(
new HtmlReporter({
path: path.join(__dirname, '../../../test-reporter'),
}),
);
jasmine.execute();
npx ts-node <Absolute_path>/src/stackoverflow/70338811/as-a-library.js
If you want to use jasmine as a CLI and run the test cases via npm script. You should add this custom reporter to the Jasmine environment. See Reporters. We need to create a helper file in src/helpers folder to add custom reporter, e.g. pretty-html-reporter.js
var HtmlReporter = require('jasmine-pretty-html-reporter').Reporter;
var path = require('path');
jasmine.getEnv().addReporter(
new HtmlReporter({
path: path.join(__dirname, '../../test-reporter'),
}),
);
npm script:
"test": "ts-node node_modules/jasmine/bin/jasmine --config=./jasmine.json",
Now, let's run test cases of a specific file.
⚡ npm t /Users/dulin/workspace/github.com/mrdulin/jasmine-examples/src/stackoverflow/69830430/index.test.ts
> jasmine-examples# test /Users/dulin/workspace/github.com/mrdulin/jasmine-examples
> ts-node node_modules/jasmine/bin/jasmine --config=./jasmine.json "/Users/dulin/workspace/github.com/mrdulin/jasmine-examples/src/stackoverflow/69830430/index.test.ts"
Randomized with seed 02843
Started
.
1 spec, 0 failures
Finished in 0.014 seconds
Randomized with seed 02843 (jasmine --random=true --seed=02843)
The test reporter is generated in the test-reporter folder.
source code: https://github.com/mrdulin/jasmine-examples

Deploing a single bash script with nixops

I'm just starting to learn nix / nixos / nixops. I needed to install a simple bash script to remote host with nixops. And I can not realize how to do it. I have two files:
just-deploy-bash-script.nix
{
resources.sshKeyPairs.ssh-key = {};
test-host = { config, lib, pkgs, ... }: {
deployment.targetEnv = "digitalOcean";
deployment.digitalOcean.region = "sgp1";
deployment.digitalOcean.size = "s-2vcpu-4gb";
environment.systemPackages =
let
my-package = pkgs.callPackage ./my-package.nix { inherit pkgs; };
in [
pkgs.tmux
my-package
];
};
}
my-package.nix
{ pkgs ? import <nixpkgs> {}, ... }:
let
pname = "my-package";
version = "1.0.0";
stdenv = pkgs.stdenv;
in
stdenv.mkDerivation {
inherit pname version;
src = ./.;
installPhase =
let
script = pkgs.writeShellScriptBin "my-test" ''
echo This is my test script
'';
in
''
mkdir $out;
cp -r ${script} $out/
'';
}
I deploy as follows. I go to the directory in which these two files are located and then sequentially execute two commands:
nixops create -d test just-deploy-bash-script.nix
nixops deploy -d test
Deployment passes without errors and completes successfully. But when I login to the newly created remote host, I find that the tmux package from the standard set is present in the system, and my-package is absent:
nixops ssh -d test test-host
[root#test-host:~]# which tmux
/run/current-system/sw/bin/tmux
[root#test-host:~]# find /nix/store/ -iname tmux
/nix/store/hd1sgvb4pcllxj69gy3qa9qsns68arda-nixpkgs-20.03pre206749.5a3c1eda46e/nixpkgs/pkgs/tools/misc/tmux
/nix/store/609zdpfi5kpz2c7mbjcqjmpb4sd2y3j4-ncurses-6.0-20170902/share/terminfo/t/tmux
/nix/store/4cxkil2r3dzcf5x2phgwzbxwyvlk6i9k-system-path/share/bash-completion/completions/tmux
/nix/store/4cxkil2r3dzcf5x2phgwzbxwyvlk6i9k-system-path/bin/tmux
/nix/store/606ni2d9614sxkhnnnhr71zqphdam6jc-system-path/share/bash-completion/completions/tmux
/nix/store/606ni2d9614sxkhnnnhr71zqphdam6jc-system-path/bin/tmux
/nix/store/ddlx3x8xhaaj78xr0zasxhiy2m564m2s-nixos-17.09.3269.14f9ee66e63/nixos/pkgs/tools/misc/tmux
/nix/store/kvia4rwy9y4wis4v2kb9y758gj071p5v-ncurses-6.1-20190112/share/terminfo/t/tmux
/nix/store/c3m8qvmn2yxkgpfajjxbcnsgfrcinppl-tmux-2.9a/share/bash-completion/completions/tmux
/nix/store/c3m8qvmn2yxkgpfajjxbcnsgfrcinppl-tmux-2.9a/bin/tmux
[root#test-host:~]# which my-test
which: no my-test in (/root/bin:/run/wrappers/bin:/root/.nix-profile/bin:/etc/profiles/per-user/root/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin)
[root#test-host:~]# find /nix/store/ -iname *my-test*
[root#test-host:~]#
Help me figure out what's wrong with my scripts. Any links to documentation or examples of the implementation of such a task are welcome.
The shell can not find your script because it is copied into the wrong directory.
This becomes apparent after building my-package.nix:
$ nix-build my-package.nix
$ ls result/
zh5bxljvpmda4mi4x0fviyavsa3r12cx-my-test
Here you see the basename of a storepath inside a store path. This is caused by the line:
cp -r ${script} $out/
Changing it to something like this should fix that problem:
cp -r ${script}/* $out/

nix-env and nix-shell have different versions of snap

I was following directions on reflex-platfrom project development,trying to test servant-reflex as a submodule.
My project is here.
In my backend.cabal, I have a built-depend:
snap >= 1.1.1.0 && < 1.2
When I nix-shell -A shells.ghc --run "cabal new-build all", it tries to install heist-1.0.1.0 and snap-1.0.0.2, then failed at
Configuring heist-1.0.1.0...
Setup: Encountered missing dependencies:
aeson >=0.6 && <1.2
To see what in my nixos-unstable, I:
`nix-channel --list`
nixos https://nixos.org/channels/nixos-unstable
`nix-env -f "<nixpkgs>" -qaP -A haskellPackages.aeson`
warning: Nix search path entry '/home/demo/.nix-defexpr/channels' does not exist, ignoring
haskellPackages.aeson aeson-1.2.4.0
`nix-env -f "<nixpkgs>" -qaP -A haskellPackages.snap`
warning: Nix search path entry '/home/demo/.nix-defexpr/channels' does not exist, ignoring
haskellPackages.snap snap-1.1.0.0
`nix-env -f "<nixpkgs>" -qaP -A haskellPackages.heist`
warning: Nix search path entry '/home/demo/.nix-defexpr/channels' does not exist, ignoring
haskellPackages.heist heist-1.0.1.2
Q: Why does nix-shell install heist-1.0.1.0 and snap-1.0.0.2, instead of heist-1.0.1.2 and snap-1.1.0.0, which then can dependent on aeson-1.2.4.0?
Got an answer from elvishjerricco on IRC #nixos.
To doJailbreak heist, you'd use the overrides argument to
project
packages is for just declaring directories that you want to turn
into haskell packages; it'll run cabal2nix for you. overrides is for
doing derivation changes to the haskell package set.
default.nix
(import ./reflex-platform {}).project ({ pkgs, ... }: {
overrides = self: super: {
heist = pkgs.haskell.lib.doJailbreak super.heist;
map-syntax = pkgs.haskell.lib.doJailbreak super.map-syntax;
};
packages = {
common = ./common;
backend = ./backend;
frontend = ./frontend;
google-maps-reflex = ./google-maps-reflex;
};
shells = {
ghc = ["common" "backend" "frontend" "heist"]; # "backend" "frontend"];
ghcjs = ["common" "frontend"];
};
})

Aliasing modules using NodeJS

Some context here: It's not that I cannot use Webpack, it's that I do not want to use Webpack. I would like to keep everything as "vanilla" as possible.
Currently when creating modules in a project you have to require them using either a relative or absolute path, for example in the following directory..
project/
├── index.js
├── lib/
│ ├── network/
│ │ request.js
│ │ response.js
├── pages/
│ ├── foo.js
Considering we're in index.js we would import request via
var networkRequest = require('./lib/network/request.js')
and if we're in foo.js we would import request via
var networkRequest = require('../lib/network/request.js')
What I'm wondering is that if there's any way to perhaps, set a local alias in Package.json or anywhere else like so:
localPackages = [
{ name: 'network-request', path: './lib/network/request.js' }
];
In which you could just do
var networkRequest = require('network-request')
From any file and it will provide the correct path.
Yep, that's what npm link is for. Native and out of the box.
You can also set local paths in package.json
{
"name": "baz",
"dependencies": {
"bar": "file:../foo/bar"
}
}

Hiera 3 + Puppet 4.2 can't manage empty value in yaml datasource

I'm facing some issues to use Hiera 3 with Puppet 4.2.
When applying my puppet manifest using this command:
puppet apply environments/production/manifests/init.pp --hiera_config=hiera.yaml
I get the following error:
Error: Evaluation Error: Error while evaluating a Function Call, Could not find data item myclass::ensure in any Hiera data file and no default supplied at /home/vagrant/temp/environments/production/manifests/init.pp:13:39 on node a
Here is the directory structure :
$ tree
.
├── environments
│   └── production
│   ├── config.yaml
│   └── manifests
│   └── init.pp
└── hiera.yaml
content of config.yaml:
$ cat hiera.yaml
---
:backends:
- yaml
:hierarchy:
- config
:yaml:
:datadir: environments/production
content of init.pp:
class myclass(
$version = $myclass::params::version,
$ensure = $myclass::params::ensure,
) inherits myclass::params {
notify {"$version": }
notify {"$ensure": }
}
class myclass::params {
$version = hiera('myclass::version', '1.0.0')
$ensure = hiera('myclass::ensure', 'running')
}
class {'myclass': }
content of hiera data source:
$ cat config.yaml
---
myclass::version: '1.0.0'
myclass::ensure:
Looks like Hiera can't handle empty values from a yaml data source and/or replace them by default value?

Resources