How do I print the current NixOS' nix.package version? - nixos

A NixOS configuration is built using the /etc/nixos/configuration.nix file. This configuration has a nix.package property.
In an NixOS instance, I want to print the version/hash (i.e., unique identifier) of the nix.package object that has been used in building the current instance. Ideally, this should be stored inside a lockfile, but I don't believe the current version of nixos-rebuild uses those.
Should this not be possible, can I explicitly store this hash somewhere during the build process by modifying my /etc/nixos/configuration.nix?

Yes, you can access this attribute via NixOS' config parameter and use it in your configuration, or as part of a package.
For example, this module causes the version and the store path to be written to files in /etc upon activation.
{ config, lib, ... }:
{
config = {
environment.etc."x-nix-version".text =
config.nix.package.version;
environment.etc."x-nix-path".text =
"${config.nix.package}";
};
}
Alternatively, you can extract it from a potentially not yet built configuration using the nixos-option command or nix repl '<nixpkgs/nixos>'.

Related

Setting debug strings dynamically in Loopback 2.0

I use debug strings for debugging Loopback 2.0 application. Loopback documentation says:
The LoopBack framework has a number of built-in debug strings to help
with debugging. Specify a string on the command-line via an
environment variable as follows:
MacOS and Linux
$ DEBUG=<pattern>[,<pattern>...] node .
Is it possible to change patterns dynamically in runtime? Or is it possible to use environment-specific configuration?
Before I get deeper note that this debug logging facility uses visionmedia's debug module which handles almost all of the logic.
Is it possible to change patterns dynamically in runtime?
Well before any module is loaded, safest and best way I believe is to just manipulate the environmental variables:
if (process.env.NODE_ENV === 'development') {
process.env.DEBUG = process.env.DEBUG + ',loopback:*';
}
Another way would be to load debug and use it's .enable method:
require('debug').enable('loopabck:*');
But note that it only works if you do this before Loopback is required since it only allows changes before it's instances are created, which is in this case before loopback is loaded. Another thing is that, there might be multiple debug modules installed depending on the dependencies and your package manager(npm#3, npm#2 and yarn behave differently). debug might be in your node_modules directory, or it might be in loopback each module, node_modules directory. So make sure you require all instances of it and enable, if you want to do it this way.
Now if don't want to do it on the startup, well API doesn't allow changes in the runtime. You can view the discussion regarding this here. Though there are some dirty ways to go around it, but these might possibly break in the future so be careful.
Firstly, there's a module called hot-debug which supposedly makes require('debug').enable work on previously created instances also, but when I tried it, it didn't work perfectly and it was buggy, but it's possible it might work fine for you.
If that doesn't work for you another way is to override require('debug').log method. If this is defined, debug will call this method instead of console.log with the formatted the arguments. You can set DEBUG=* and then filter it yourself:
require('debug').log = function (string) {
if (string.contains('loopback:security')) {
console.log(string);
}
};
This way will be slow in production though as all the debug output will be formatted before being filtered even though nothing might be outputted to console.
Another thing to override the require('debug').init method. This is called everytime a new debug instance is created. Since every debug instance uses an enabled property to check if it's enabled we can toggle that.
const debug = require('debug');
const { init } = debug;
const instances = [];
debug.init = function(debugInstance) {
init(debugInstance);
instances.push(debugInstance);
};
// You can call this function later to enable a given namespace like loopback.security.acl
function enableNamespace(namespace) {
instances.forEach(instance => {
instance.enabled = instance.namespace === namespace;
});
}
Though there's a lot of improvement can be done on this, but you get the idea.
I can change debug namespace dynamically with the hot-debug module.
In my app, I've just created a function for this :
require('hot-debug')
const debug = require('debug')
function forceDebugNamespaces (namespaces) {
debug.enable(namespaces)
}
// Usage
forceDebugNamespaces('*,-express:*,-nodemon:*,-nodemon')
In my case, I have a config file which allow me to set process.env.DEBUG but I needed to find a way to update debug namespaces without restarting my app (the config file is watched for changed by my app).

How can I override a Nix derivative without throwing `cannot coerce a set to a string`?

Or, the goal: How can I take a single package from Nix unstable in a declarative manner?
I'm new to NixOS and currently trying to install a newer version of Consul than the default 0.5.2 of my NixOS version (latest stable). I'm attempting this by overriding the derivative in my /etc/nix/configuration.nix.
I'd like to keep running stable, but I found unstable had the version of Consul that I wanted (0.7.0) already, and so I decided to use this package's attributes as a starting point to override https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/consul/default.nix
I copied it for most part into my configuration.nix, here are the relevant sections:
nixpkgs.config.packageOverrides = pkgs: rec {
consul = pkgs.lib.overrideDerivation pkgs.consul (attrs: rec {
version = "0.7.0";
name = "consul-${version}";
rev = "v${version}";
goPackagePath = "github.com/hashicorp/consul";
src = pkgs.fetchFromGitHub {
owner = "hashicorp";
repo = "consul";
inherit rev;
sha256 = "04h5y5vixjh9np9lsrk02ypbqwcq855h7l1jlnl1vmfq3sfqjds7";
};
# Keep consul.ui for backward compatability
passthru.ui = pkgs.consul-ui;
});
};
environment.systemPackages = with pkgs; [
vim
which
telnet
consul-ui
consul-alerts
consul-template
consul
];
I'm running nix-build (Nix) 1.11.2 which throws:
$ nixos-rebuild switch
building Nix...
building the system configuration...
error: cannot coerce a set to a string, at /etc/nixos/configuration.nix:19:7
(use ‘--show-trace’ to show detailed location information)
When I look at line 19 it's where name is set to "consul-${version}".
Why there is type-coercion going on here? Any tips will be greatly appreciated!
I'm also wondering if there is a better way to run just a single package in unstable, yet doing so declaratively from configuration.nix, rather than imperatively?
To add to what Rok said:
Which should point you that an error actually happens at passthru, line. If you comment it out it will probably build. I'm assuming some recursive calls are at play here and error occurs when it tries to evaluate consul/consul-ui packages.
If you're just starting out, you can safely ignore what follows and perhaps come back to it if/when you're curious about the nitty-gritty.
The problem here is that overrideDerivation is a kind of low-level approach to overriding things. Behind stdenv.mkDerivation, we have a much smaller primitive function called derivation. The derivation function takes some attributes and (more or less -- see the docs for the finer details) just passes those attributes as environment variables during the build. The stdenv.mkDerivation function, on the other hand, has a whole bunch of smarts layered on top that massages the attributes given to it before passing them onto derivation -- and in some cases, as is the case with passthru, it doesn't pass the attribute to derivation at all.
Back to overrideDerivation: it takes the final, tweaked attributes that stdenv.mkDerivation would pass to derivation, and just before that happens it allows you to override those attributes with the function you give it (e.g. that implies that, at that point, passthru has already been removed). When your function adds a passthru, that makes its way into derivation, which then wants to coerce the value of passthru into a string so it can make passthru an environment variable during the build; however, because passthru now points at a attribute-set, and such coercion isn't supported, Nix then complains.
So this sort of puts us in an odd situation. To illustrate, I'll copy the source for the consul package here:
{ stdenv, lib, buildGoPackage, consul-ui, fetchFromGitHub }:
buildGoPackage rec {
name = "consul-${version}";
version = "0.6.4";
rev = "v${version}";
goPackagePath = "github.com/hashicorp/consul";
src = fetchFromGitHub {
owner = "hashicorp";
repo = "consul";
inherit rev;
sha256 = "0p6m2rl0d30w418n4fzc4vymqs3vzfa468czmy4znkjmxdl5vp5a";
};
# Keep consul.ui for backward compatability
passthru.ui = consul-ui;
}
(Note that buildGoPackage is a wrapper around stdenv.mkDerivation.)
You might be familiar with e.g. consul.override, which allows you to supply different inputs (e.g. maybe a different version of consul-ui, or buildGoPackage), but it doesn't allow you to override things that aren't inputs (e.g. src, passthru, etc). Meanwhile, overrideDerivation allows you to modify the attrs given to derivation, but not the ones given to stdenv.mkDerivation. Ideally there would be something in-between, that would allow for manipulating the attrs given to stdenv.mkDerivation, and it so happens that there's a PR open to address this:
https://github.com/NixOS/nixpkgs/pull/18660
Welcome to Nix/NixOS :)
Whenever you need to know more about the error you can use --show-trace and that would give you more verbose error. In your case you would see something like
error: while evaluating the attribute ‘passthru’ of the derivation ‘consul-0.7.0’ at /home/rok/tmp/consul.nix:6:3:
cannot coerce a set to a string, at /home/rok/tmp/consul.nix:6:3
Which should point you that an error actually happens at passthru, line. If you comment it out it will probably build. I'm assuming some recursive calls are at play here and error occurs when it tries to evaluate consul/consul-ui packages.
As for overriding only one package from unstable channel something like this is needed
let
unstable_pkgs = import ./path/to/unstabe/nixpkgs {};
# or
# unstable_pkgs = import (pkgs.fetchFromGitHub {...}) {};
in {
...
nixpkgs.config.packageOverrides = pkgs: rec {
consul = unstable_pkgs.consul;
};
...
}
I haven't try the above, but I'm assuming it will work.

Global resources in Puppet

Is it possible to add a global resource?
I have about 1000 nodes with different configurations and now I want to install a package on every single node. Can it be done in site.pp?
I have a default node, but from what I can tell it is only for unrecognised nodes so I don't think this is the way to change it.
This will depend on the way you have written your puppet manifests. If you have a class included on every node, then you could add the definition to that.
You could user hiera to allow you to customise the default packages on a per machine basis. If you had a module called siteconfig, then you could could create a class something like;
modules/siteconfig/manifests/init.pp
class siteconfig {
include siteconfig::defaults
package{$::siteconfig::params::packages:
ensure => 'present',
}
}
modules/siteconfig/manifests/params.pp
class siteconfig::params(
$packages = []
) {
validate_array($packages)
}
and then define siteconfig::params::packages in hiera as an array of packages to be installed by default. This means that you could easily add more default packages by editing the array in hiera, and you could customise it on a per-host basis.
Bonus points if you work out how to use create_resources instead!

How to create predictable logging locations with sbt-native-packager

I am using sbt-native-packager with the experimental Java Server archetype. I am trying to identify a conventional way to access my log files, and I'm wondering if anyone knows of a common approach here. Since I am using the Java Server archetype, I am getting a symlink /var/log/$app -> install_dir/$app/log, but it feels a little dirty and less portable to just have log4j open /var/log/$app/error.log directly.
[Update]
I ended up creating an object with run time path information:
object MakaraPaths {
def getLogPath = new File(getJarPath, "../logs").getPath
def getConfigPath = new File(getJarPath, "../conf").getPath
def getJarPath = {
val regex = new Regex("(/.+/)*")
val jarPath = Makara.getClass.getProtectionDomain.getCodeSource.getLocation.getPath
(regex findAllIn jarPath).mkString("")
}
}
In my main method, I established a system property based on the new MakaraPaths object:
System.setProperty("logPath", MakaraPaths.getLogPath)
I also used this for my config file:
val config = ConfigFactory.parseFile(new File(MakaraPaths.getConfigPath, "application.conf"))
Ultimately, to load the log file, I used a System Property lookup:
<RollingFile name="fileAppender" fileName="${sys:logPath}/server.log" filePattern="${sys:logPath}/server_%d{yyMMdd}.log">
This gets me most of the way where I needed to be. It's not completely portable, but it does technically support my use case. (Deploying to Ubuntu)
You could use relative path in log4j configuration. Just write logs in logs/filename.log.
During installation symlink install_dir/$app/logs -> /var/log/$app will be created, and all logs will be written in /var/log/$app/filename.log

move the reference to working directory using libgit2sharp

I want to change the reference to the working directory to a different place using LibGit2Sharp in a Visual C++ project. it seems to me that Repository::Init() with RepositoryOptions can set the working directory to a non-default place. What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init(). Repository::Info::WorkingDirectory seems to a be read-only property, so I can't change it through this route.
Any thoughts on how to accomplish this? or the equivalent of git_repository_set_workdir() is not exposed in LibGit2Sharp.
What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init().
Repository.Init() puts a folder under source control by creating a new repository on the filesystem. It returns an instance of the created repository.
The constructor of the Repository type gives you acces to an existing repository. This constructor accepts an optional RepositoryOptions parameter to override some options.
In order to fulfill your request I'd go with something like this
var path ="D:\path\to\your\repo";
using (var repo = Repository.Init(path)
{
// Do nothing here
}
var newWorkdir ="D:\path\to\your\other\working\directory";
var options = new RepositoryOptions { WorkingDirectoryPath = newWorkdir };
using (var repo = new Repository(path, options))
{
// Do YOUR amzing stuff ;-)
}
Update:
The config file of the repo does not have the worktree attribute set to the right place, and the new working directory does not have a .git file pointing to the repo folder, as what you would expect.
This is the expected behavior. Passing a RepositoryOptions type to the constructor temporarily overrides some settings of the Repository. Once the repo is disposed, those temporary settings are lost.
I check the libgit2sharp source code for repository.cs and happen to notice that when it calls git_repository_set_workdir, it only has two arguments, as opposed to three
The bound libgit2 method is invoked with three params, the third one being set to false, because we do not want to persist the temporary settings when instanciating a repository.
Back to your original question: "What I am trying to do here, however, is to change the reference to the working directory for the repo AFTER it is created by Repository::Init()."
This is currently not possible with LibGit2Sharp. However, it might be possible to make this happen DURING the call to Repository.Init() through the addition of an optional parameter. If this looks like something may fit your need, I'd suggest you to open an issue regarding this topic, or even better, send a Pull Request ;-)
Another option would be for you to manually set the core.worktree config variable to the expected location (You'd have to deal with the creation of the gitlink by yourself, though):
The code below demonstrates this last option:
var path ="D:\path\to\your\repo";
// Note the use of forward slashes here
var newWorkdir ="D:/path/to/your/other/working/directory";
using (var repo = Repository.Init(path)
{
repo.Config.Set("core.worktree", newWorkdir);
}
using (var repo = new Repository(path))
{
// Do YOUR amzing stuff ;-)
}
Update 2:
LibGit2Sharp has just been updated with PR #453.
Among other things, this makes repo.Init() accept a separate git directory, which should fit your requirements.

Resources