musicmatzes blog

I've done it. This blog post is written from my NixOS installation on my new machine. Have a look inside to see a screenshot and my experience with the actual setup of a real machine with NixOS.

So, the setup is not that simple, so I ran into some issues, of course. But maybe I should list my hardware first, at least the relevant parts:

  • Processor: AMD FX-8320 (8 x 3,5 GHz)
  • Graphics Card: MSI AMD Radeon R9 270X Twin Frozr 2GB GDDR5
  • Motherboard: Gigabyte GA-990FXA-UD3

Plus two 3TB WD drives and a 120 GB Samsung EVO SSD. I guess the other parts are not relevant here and now.

Configure all the things!

I started by doing a simple NixOS installation, everything worked. Then I restarted it and encrypted the drives. This got me into some trouble, because it did not work that simple. After booting with the appropriate settings (for encryption), the bootloader was shown and after that there was just nothing shown. It was really scary! After adding the ext4, dm_crypt and the fbcon (which is for message printing during early boot) I got the password prompt from luks, so everything was fine from there. I had to play around with the actual cryptdevice configuration, but I got it working really fast. After that, I simply copied my configuration.nix over to the machine and tried to rebuild the system. It failed. But it failed because of a simple reason: I added a 900,000 lines /etc/hosts entry to my nix configuration before copying it over to the machine. That was a bit too much, so I had to comment it out.

I'm running on NixOS for a few weeks now and I still have some problems, but they are all very specialized ones. For example, I use youcompleteme as autocompletion engine for vim. But it cannot find the standard headers, as these are obviousely not installed in /usr/include! That's one of the issues I can remember at the moment. But hey, it works!

tags: #linux #nixos

I just discovered that the a.vim plugin almost breaks my vim flow.

Here's why.

You might know the a.vim plugin. It was made to switch between source file and header file, including split-opening it and so on. It is really neat and I really like the idea. So I installed it. But unfortunately, it uses some insert-mode mappings which are mapped on <Leader> ... something. And as my Leader is space, it completely broke my vim flow, as everytime when I hit space, vim waits to complete my mapping... but I wasn't actually using a mapping, I was just typing.

This little offset broke everything for me... I could barely use vim. You might now say that I could set the timeout for vim to something small, like 300 or something. I tell you: No! It's just not the same.

So, I removed the a.vim plugin again. Sadly. Maybe there is an option to configure on what it is mapped, but I really don't care this much anymore!

tags: #programming #vim

Some of you might know my little project rate. It is a bash script to collect a database of things you want to rate.

What this means and why I started to reimplement in C++ – read it here!

So I started to write this application because I wanted to keep track of animes I already watched, Bands I like but do not listen to that often and so on and so forth. What the application does is really simple: You can enter notes about a certain thing (in your favourite text editor, which is vim for me) and attach tags to it and put it into a category. Then you can give it a rating. The rating can be everything, from simply numbers to text to whatever you like. But it is supposed to be a number between 1 and 10, of course. That's also the way I use it.

So how does it work? Well, that's really simple: The “rate” script creates a directory structure in ~/.rate/collections/, whereas a folder is a “collection” of things and a file is a rating. So, I have something like “movies/animes/” as collections (they are nested, of course) and then a file for each anime I watched. The filename is generated from the title I passed “rate” when creating the entry. The file also contains a “header”, which includes a unique ID (which you really should not change), a list of tags, the title (the filename is the title, too, but as on linux you shouldn't include whitespace in file names, it is not the title as you typed it) and a rating of course. Custom fields could be added to the header, but this feature is not implemented yet. After the header, you can put your description.

That's basically it. “rate” provides some features to search this database, for example you can grep for text in your entries, you can view your entries, you can list your entries and you can attach more text to your entries or edit them. As everything is git controlled in the ~/.rate directory, you can reset if you (or the script,...) messed up somehow.

There's no release by now, as it lacks of some features by now. For example I want to be able to search for entries with a certain rating or within a certain range of ratings. I also want to be able to search for entries with aspecial set of tags or within a certain collection (I can do this, though) special set of tags or within a certain collection (I can do this, already)! After these things are implemented, I will release my first version, which would be 1.0 then. And, of course, I will package it for NixOS!

So why C++

Well, I have to learn C++ for my praxis semester. That's basically it. I wanted to learn a new programming language for a relatively long time, and that's my approach on learning C++. I was able to implement some things, but not yet to run an application. My first step would be to parse my already existing entries. Hope that works. As I stated in the github repos README.md file, I do not want to use any frameworks for this. No Boost, no Qt, no other libraries. I just want to use plain C++11 (or maybe 14 in future, not sure about this, though).

Also, C++ gives me way more posibilities when it comes to features. I can refactor things really easy and maybe the C++ implementation will continue to live whereas the bash implementation will die at some point. Who knows? The point is, the bash implementation implements a file format which is

  1. really simple
  2. forward compatible

The file actually looks like this:

key = value
other = value
another = another
---

<text>

and that's basically it. The three dashes mark the end of the header and everything before the header is a <key> = <value> list, whereas each line is only allowed to contain one key-value-pair. The value can be a list of values, for example a list of Tags whereas tags are seperated by a whitespace character (space) or a string, such as the title is. The bash implementation “knows” which key has to be which value and the C++ implementation has to know this, too, of course. But that's it.

The commandline interface of the application needs some work, though. Maybe it will get some REPL-like interface later on, or maybe something more interactive. By now, it is simply an interface where you can do one thing per call. I have no problem with that and I'm planning to keep backward compatibility with the bash implementation even if this one is not even released! It is fun to write such a tool and I really like doing it.


Also, it is not a that complex thing to implement and that's a huge point to me. I don't want to spend months and months in implementing a thing which only one or two people on this planet actually use. For bigger projects, I contribute to open source projects. That's a better way to produce large-scale software, IMHO.

tags: #bash #programming #c++ #linux #shell #vim

In this part of the series, I will describe my bash setup, as I promised at the end of the last part of the series.

Also, I finally ordered my new machine! I will, of course, show you some facts about the machine and as soon as all parts have arrived, I will publish an article about building the machine etc!

But first, the bash setup. If you've read the last part of the series, this won't be that special for you. The approach is similar, but not that complex, of course.

So first, I had to add a new subdirectory in my ~/config/nixos/ directory. I named it programs, as all program configuration should go there. Inside this directory there is a directory named bash. Inside these directories there are the normal default.nix files.

The programs/default.nix file looks like this:

{
    programs.bash = import ./bash/default.nix;
}

So nothing special here. The programs/bash/default.nix file looks almost similar:

{
    shellAliases            = import ./aliases.nix
    enableCompletion        = true;
    promptInit              = builtins.readFile ./prompt.sh;
    interactiveShellInit    = builtins.readFile ./functions.sh;
}

Here I import the aliases, which are specified in pure nix. I also enable the completion for bash and I read the prompt.sh and functions.sh file which are located in the same directory. These files are normal bash scripts.

And that's basically it! Nothing complicated here, as you see! Of course, you can still provide your normal ~/.bashrc file and define your stuff here, but for a system-wide bash configuration, this is just awesome! Your bash setup gets compiled into your system, which means when going back to a previous configuration, the bash configuration goes back to! I really like that! And, of course, you should also be able to ship your bash configuration to a remote host. But I'm not sure about this one.


I also managed to get my next package into the luakit repository: luakit! I finally packaged luakit for nixos. It is not battle-tested yet, but as luakit will be my next browser, I will battle-test it as soon as I'm on NixOS myself!


Well, this article was rather short, but I have nothing more to tell you right now. Maybe next week, if I managed to build my machine until then!

Stay tuned! tags: #linux #nixos

I started a fork of a diary application which is written in bash, because I thought there are some things missing and some features could be added – and the repository of the original author was really old.

I started to pretty it up and implement some 21st-century things so it becomes a really nice note-taking application.

So, initially the application was called “diary” and developed on sourceforge, by Jamie Briggs. Someone created a fork, named “diary-f”, which added some features.

The lastest change in the original repository is from February 2013, which is almost two years ago by now. The last change in the repository of the fork is from three years ago – even longer, yes!

So, the application per se is really good one. It is just a small shell script, but it works really good for me. Anyways, I missed some features, namingly:

  • Multiple separate entries per day
  • Everything should be kept in git, so I know when I edited the articles
  • GPG encryption everywhere

I started implementing multi-file support directly in the “diary-f” repository, but then decided to create a fork, as it won't be compatible with the original software anymore. By now, three things are done in the repository: I refactored the codebase to fit my coding style (well, it is still bash, isn't it?), mutli-file support as said and git support. I want to implement gpg support next and maybe the ability to add attachements to entries. And after these things are implemented, I want to be able to search the entry repository for certain entries in a simple way, which could be difficult, given the fact that everything is encrypted in there.


If you're interested in the application, I'd welcome pull requests for almost everything. Contributing guidelines are:

  • Document your work, how do things work?
  • KISS
  • DRY

That's basically it. I'm looking forward to your patches! tags: #bash #git #open source #programming #shell #tools

So I promised I will explain my vim setup in this part of the series. And of course, I will do this.

The requirements

The requirements are fairly easy here. I wanted to be able to use YouCompleteMe with vim, so I need a vim with Python support enabled. So, I absolutely need the configurable vim package from the NixOS package tree and I clearly must override it. And when doing this step, I can remove all the stuff from the vim package I do not need.

Another requirement was that I can replace vim with neovim. I've not done this yet, but I guess it should be fairly easy.

Because not all vim plugins are in the NixOS packages, I need to be able to build my own packages outside of the NixOS package tree and pack them into my store as well.

And, because vim needs to know all these plugins, I must be able to override the runtimepath variable in the vim configuration, the vimrc. So, I need to be able to compile the vimrc out of the package definition as well.

The setup

The directory setup here is fairly easy. I have my normal configuration folder whereas I created a folder vim inside the pkgs folder:

config/nixos/ | +– ./pkgs/ | +– vim.nix +– vim | +– override.nix +– pkgPlugins.nix +– plugins.nix +– vimrc/ | +– colorscheme.vim +– filetypes.vim +– ... +– vimrc.nix

Let me elaborate what is located where here.

vim.nix

The top-level file for the vim packaging. This file is actually included in my machine-specific configuration or in the pkgs/basePackages.nix file, so my vim is always installed on every system. The latter is the way I want to do this, so I have the same vim on all systems.

This file returns a list.

vim/override.nix

This file simply contains the overridden vim package.

This file returns a package / derivation.

vim/pkgPlugins.nix

This file contains the already packaged plugins. I do not have to compile them, as they are already in the NixOS package tree, which makes certain things simple but others more complex, we will see why.

This file returns a list.

vim/plugins.nix

Self-packaged plugins. Period.

This file returns a list.

vim/vimrc.nix

This file uses all files in pkgs/vim/vimrc/*.vim and compiles them into one giant string and writes this one as vimrc file to the store. Actually, there is a pkgs/vim/vimrc/plugins.nix file in the directory which compiles pkgs/vim/vimrc/plugins/*.vim files into a string and returns that string, which simply gets included in the vimrc. I did this for abstraction, so the configuration for each file lives into the appropriate subdirectory.

The How

Lets start with the easy parts here first. To override vim, you don't really have to do much things. What you have to do can be explained best with the appropriate nix file:

Override vim

{ pkgs, lib, vimrc }:

let vim = lib.overrideDerivation pkgs.vimconfigurable (o: { aclSupport = false; cscopeSupport = true; darwinSupport = false; fontsetSupport = true; ftNixSupport = true; gpmSupport = true; hangulinputSupport = false; luaSupport = true; multibyteSupport = true; mzschemeSupport = true; netbeansSupport = false; nlsSupport = false; perlSupport = false; pythonSupport = true; rubySupport = true; sniffSupport = false; tclSupport = false; ximSupport = false; xsmpSupport = false; xsmpinteractSupport = false;

postInstall = (o.postInstall or “”) + '' ln -sf “${vimrc}” “$out/share/vim/vimrc” ''; }); in vim

Of course, you have to make sure that this is the only occurance of vim in your package setup. And if you install vim in a user environment, it will override this as well, so be warned!

So I ripped out everything I don't need here, which is for example tcl support. I don't even know what tcl is, actually.

You also need to override the postInstall hook to ensure you link the vimrc to the appropriate path. The vimrc file must be passed to this function, as you can see in the first line.

Packaged plugins

The second thing which is fairly easy is the file for the plugins which are already in the NixOS package repository. What I do here is simple:

{ stdenv , pkgs }:

[ pkgs.vimPlugins.youcompleteme # pkgs.vimPlugins. # ... ]

And yes, it is that simple. I will not share my entire config files here, of course. You don't need to know what kind of plugins I use in my vim setup!

More plugins!

Now comes the more difficult part. I actually copied these definitins from aszlig:

{ stdenv , pkgs , lib , writeTextFile , writeText , buildEnv , fetchgit , vim_configurable }:

with stdenv;

let

# ... here were some things I did not need

mkVimPlugins = plugins: buildEnv { name = “vim-plugins”; paths = with lib; mapAttrsToList (const id) plugins; ignoreCollisions = true; postBuild = '' find -L “$out” -mindepth 1 -maxdepth 1 -type f -delete ''; };

pluginDeps = { };

plugins = mkVimPlugins (pluginDeps // {

vimvim-fugitive = fetchgit { url = “https://github.com/tpope/vim-fugitive"; rev = “”; sha256 = “”; };

# ...

});

in [plugins]

As you can see, this file is a bit longer than the previous ones. I only inserted the fugitive plugin for posting here, obviousely. So how does this work? Each plugin gets fetched with git (for fetching from vimscripts or other methods of fetching, look at aszligs repo, this file, actually). After it was fetched from git, it is inserted in a set which is afterwards fed to the mkVimPlugins function, which adds all the plugins to one package. All plugin pathes are added to the package then. Why you need the ignoreCollisions = true; line... I'm not sure but I guess it ensures that two plugins can have files with same names. I'm also not sure about the postBuild hook.

But that's how it is supposed to work. It returns a list of plugins, then.

Lets build a vimrc!

Yes, I actually compile my vimrc out of nix expressions. That's not that hard, it is actually string concatenation, because I do write .vim files.

{ stdenv, writeText, additionalRTP }:

let

generic = builtins.readFile ./vimrc/general.vim; # ... statusline = builtins.readFile ./vimrc/statusline.vim; # ...

plugins = import ./vimrc/plugins.nix;

in

writeText “vimrc” '' ${generic}

set runtimepath+=${additionalRTP} set runtimepath+=${additionalRTP}/after set runtimepath+=${additionalRTP}/share/vim-plugins

${statusline}

${plugins} ''

That's really easy: I read the files which contain the vim configurations (general configuration, statusline, etc) and put them all together.

What I add as well: The additional runtime path. This is actually required because when installing vim packages which are not in the package tree of NixOS by now, vim cannot find these. When adding the additional runtime path here, I tell vim to look in these directories as well, ensuring that the plugins can be found.


The last point is obviousely one point I have to clean up, because I guess there should be a better way how to do this. As you might notice when setting up your vim configuration on NixOS, there is also an plugin manager for vim you can use from within NixOS/the nix packages. It gives you lazy loading of vim plugins and all these nice things you want to have. I'm not sure how this fits into the way how NixOS packages vim plugins, I guess I have to dig around here a bit.

Anyhow, it works. On my testing machine, which is an rather old machine (not that old, but also not the new shit, you know) vim starts up in about 1 second. This is obviousely way to much for a machine I want to use for developing software, but for this machine it is okay.

Maybe this will get better after cleaning up the setup, I'm not sure.


In the next part of the series, I will explain my bash(rc) setup, which is handled by nix, of course. Maybe I can also elaborate on my vim setup, if I managed to clean up the mentioned parts. tags: #linux #nixos

Some people always tell me that “mailinglists are so 1990” or something. And yes, of course, email is an old protocol and everything. But that does not mean that it is bad.

Here is why I love mailinglists

I get a lot mail. About 1k mails per day, whereas most of them are mailinglists. Actually, the most of them are from the linux kernel mailinglist and I automatically drop them into a folder where I do not look at that often. But when I need to, I can.

But that's not the point of this post, actually. This post is about why I love mailinglists and think mailinglists are a better way of communication compared to, for example, the IRC chat.

When writing in IRC, you have to type quickly, depending on how many people are in the room and talking at this moment. You can hold discussions with several other people, but as soon as several people talk at the same moment but about different topics, things get nasty. That's not the case on a mailing list.

A discussion often starts with a question, a suggestion or maybe an announcement. Then, people comment on it, the discussion beginns. Because mails are persistent in a way chats will never be, one can talk his time to formulate a response. Discussions are seperated in subthreads, which is way more convenient than talking in IRC, getting from one point to another but never beeing focused on the discussion as one discussion but a chain of.

Also, on mailing lists one can focus on single points others make in their statements by quoting them in a really convenient manner. One can remove parts of the statements of others when replying, which forces everyone to focus on the actual points and not the stuff around it, which may be relevant, but often is not. When people talk over a mailinglist, you can read that afterwards to get a clue what is going on. I often search mailinglists for solutions of my problems rather than wikis or something, where problems are generalized and often do not match with my actual problems.

And, of course, if a mailinglist is open, one can post to it without beeing subscribed, which is really a good thing if you want to solve a problem which occours once but never again. Example: I try to configure my mail client at the moment, my offlineimap configuration, actually. I had several issues (related to eachother, of course), so I posted on the mailinglist for offlineimap, where people help me. After the problem is solved (it is not by now...) I will forget this mailinglist again, as I'm not subscribed to it. I don't care afterwards about offlineimap, because it should just work for me and that's it.

So, these are my points why mailinglists are a great tool for getting problems solved, doing discussions and the like. Please note that I do not think the IRC should be abandoned in favour of mailinglists. I love writing with people in IRC, too. But for solving problems, mailinglists are way better for me.

tags: #mail #mailinglists #social #irc #chat

In the last part of the series I described what my requirements for a NixOS installation are and why I wanted to switch to it (and KDE).

In this part I describe how I installed my second machine (a Toshiba Notebook) with NixOS and how I got some things running.

The machine

I had NixOS installed on a virtual machine in the first place and I already had it on the mentioned Toshiba Notebook. But this installation was removed in favour of a complete reinstall (including disk formatting and everything). So this is actually a installation from scratch, whereas I kept the configuration files.

The machine I installed NixOS on is a Toshiba Notebook, a Toshiba Satellite PRO S300L.

Machine Data:

  • Intel Core 2 Duo Processor @ 2,00 GHz
  • 3 GB RAM
  • 160 GB HDD
  • Mobile Intel GMA 4500MHD Graphics
  • 15,4” WXGA TFT Display

Yes, it is an old machine, but that does not matter.

The Installation

The installation was really basic. I actually followed the NixOS installation guide pretty much.

After booting the live image, I formatted the disk to have approx. 75GB for the root partition and the rest (which was another approx. 75GB) for /home. I did that because I want to play with this machine, so a big root partition is important for me at this point. For a productive installation on this machine I would've used only 50GB, but not less. The Nix package manager actually needs more disk space for the packages as other package managers, but that's part of the approach and won't change in future, I guess. Anyhow, 75GB is not that much nowadays!

I formatted both partitions with ext4. Pretty basic stuff here, no encryption or something, no LVM, actually.

After this stuff was done, I copied the configuration file from my backup stick to /etc/nixos/configuration.nix, including all the parts I outsourced into .nix modules and fired up a nixos-install. It build my complete system, which I was able to boot afterwards!

Now, how's that, Archlinuxers? It actually build my entire system including boot loader, mount points, services and desktop! I can actually use this piece of hardware now! I can use it productively!

That's my sellings point No. 1 of NixOS! You don't have to mess around anymore!

The KDE desktop.

I did some small configurations for the KDE desktop. Actually, I bound ALT-j, ATL-j, ALT-k and ALT-L and so on, to have some basic vi-like key bindings.

I also added some desktop widgets, but that's not of a big deal as well.

Here are some screenshots:

Blank KDE

Dirty KDE

Nothing interesting, huh? It's just a basic KDE desktop, of course!


So, in the next part I will elaborate a bit on my configuration setup. Maybe I will explain a bit of the syntax of the Nix expression language. I will clearly elaborate on the appraoch and maybe show a way how to build another system out of the already provided parts of my configuration.

Stay tuned!

tags: #linux #nixos

I have a problem. I want to write a small application. It should be a commandline application, but maybe I want to extend it later with a GUI or even a web interface. But I don't know what language to write it in.

This article could also be named “Which is the right tool for the job?”

The idea is simple: I want to write a journal-application, where one can take notes, tag them, query the journal for entries, optionally provide filters before printing them to print only some of them and so on.

I want to be able to encrypt them with gpg and I want to write posts to the journal with vim. I want to be able to configure these steps, of course, so I can use a certain key for encrypting the journal or maybe another editor (for these emacs lovers out there).

It should be designed to be extensible, so I can add a GUI or web interface later on. Or maybe a tex output, so I can compile a PDF out of it or something. Posts should be written in standard markdown, so this wouldn't be a big deal.

But I don't know what language to write it in. The languages which I can or would choose from are:

  • C
  • C++
  • Haskell
  • Rust
  • Java (not really...)
  • Scala (not really either, it's still JVM)
  • Ruby
  • Python (by extending jrnl)
  • Racket
  • Lua
  • Bash (I really don't want to write it in bash, but it's still a possibility)

As you can see, the first four languages are compiled languages, then Java and Scala are (lets call it) Semi-Compiled languages and the others are scripting languages. All of these languages have certain advantages over others.

The compiled languages

... have the advantages that they are fast. Haskell and Rust also have the advantages that if the compiler does not fail compiling the sources, the program just works ™.

Also, learning C++, Haskell or Rust would be a really great experience and may be beneficial later in a job or something.

The semi-compiled languages are also (kind of) fast, but they are JVM-languages, so I won't look into them here...

The scripting languages

Writing the application in a scripting language would have some other advantages: They would be much more flexible and I'd be faster writing the application (compared to Rust or Haskell, which I would need to learn with the application). I don't need to learn Ruby, I know a fair bit of Racket and I guess I can get productive with Python or Lua really fast.

Bash is another option and I'm actually an bash script for an almost similar job right now. I could simply extend this script, that would be an option, of course.

So which is the right tool for the job?

Can you tell me? I don't know which tool is the right tool for the job. After all, I don't think I should write such an application from scratch. So, for me, there are two options left: Extending jrnl, which is an Python script, or extending diary (I do not even find a link for this anymore), which is a bash script. Extending the bash script would be an easy job, I guess. But it wouldn't be as flexible as the Python tool is already. tags: #bash #c #c++ #haskell #programming #racket #rust #shell #tools

In the last part of the series I descripted what I did to install KDE on the machine and promised to explain the configuration setup in this article.

The KDE was removed since, as I read some comments from people raging against Kontact/KMail/Akonadi and that it is bloat which does not work. So, I'm back at i3 and the “old” setup. Anyways, the configuration setup did not change, and I will explain it in this part of the series.

Kontact or no Kontact

So, Akonadi, KMail, Kontact and the whole stuff does not work. I've heard that from several people at reddit and in several IRC channels. So I'm back at my old setup, including

  • offlineimap / msmtp for mailing services
  • mutt as mailreader (was: Kmail)
  • remind as calendar (was: KOrganizer)
  • wyrd as calendar interface (was: KOrganizer)
  • taskwarrior as task tool (was: KOrganizer)
  • abook as address book (was: KAdressbook)

The point is, that I must get this tools to get working with eachother properly to have something like Kontact. And I will do so.

But, of course, this is another problem and I will explain it in another blog post, maybe.

The configuration setup

That's the part you're interested in most, I guess. So here we go. I've already described the problem, I have several machines, which have some parts of configuration which is same on every machine, but some parts differ.

My approach is simple. I have several subsets of configuration I can include into eachother to build a complete configuration. My folder structure looks like this:

~/config/ | +– nixos/ | +– fs/ +– nixpkgs/ +– pkgs/ +– services/ +– users/

in ./nixpkgs/ I simply symlinked the ~/.nixpkgs/config.nix for version controlling purposes (~/config is a git repository on my machines).

So, I have several sets of configuration sorted by kind of configuration.

fs

The ./fs/ subdirectory contains file system configurations for each machine. Of course, these parts cannot be re-used by other machines most of the time, but I keep them in a special subdirectory to keep my setup clean and modular.

A file ./fs/some.nix looks like this:

{ ... }: { fileSystems.“/home” = { device = “/dev/sda2”; fsType = “ext4”; options = “nosuid,nodev,relatime”; }; }

for example.

pkgs

In the ./pkgs/ subdirectory, there are package sets defined. Namingly:

./pkgs/ | +– basePackages.nix +– desktopPackages.nix +– devPackages.nix

by now. Each of these files look like so:

pkgs: [ pkgs.mosh pkgs.tmux ... ]

for example.

services

A file in ./services/ defines one service. I can include a service file for simply “installing” the services.

My ./service/ file for redshift looks like this, for example:

{ services.redshift = { enable = true; latitude = “48.059402”; longitude = “8.464087”; temperature = { day = 5500; night = 3700; }; }; }

Simple stuff.

users

And last, but not least: ./users/. I don't think I have to explain this one, it looks like the service or file system definitions.

The machine configuration

What's more important and interesting, is the actual machine configuration. The machine configuration is a single file which lives in my ~/config/nixos/ folder and is named like the host.

So, nox.nix, which is the configuration file for my testing machine, looks literally like this:

{ config, pkgs, ... }:

let configDir = /home/m/config/nixos; in

{ imports = [ # Base configuration “${configDir}/base-configuration.nix”

# Users “${configDir}/users/m.nix”

# Services “${configDir}/services/synergyClient.nix” “${configDir}/services/x.i3.nix” “${configDir}/services/redshift.nix” “${configDir}/services/networkmanager.nix” ];

# Define on which hard drive you want to install Grub. boot.loader.grub.device = “/dev/sda”;

networking.hostName = “nox”;

environment.systemPackages = let basePkgs = import “${configDir}/pkgs/basePackages.nix” pkgs; devPkgs = import “${configDir}/pkgs/devPackages.nix” pkgs; desktopPkgs = import “${configDir}/pkgs/desktopPackages.nix” pkgs; in basePkgs ++ devPkgs ++ desktopPkgs;

}

That's the whole deal. You may notice, that there is a base-configuration.nix, I include in this file. This is a very generic default configuration for each machine. It simply defines the following stuff:

  • use grub2, but not where to install it
  • system language
  • default shell (bash for me)
  • timezone
  • enable “sudo”

So this is really just basic stuff each machine has to be configured to.

After linking the /etc/nixos/configuration.nix to the appropriate file in the configuration directory, nixos can be rebuild and everything just works ™.

Feel free to copy the described setup and adjust so it fits your needs! Feel also free to ask me questions about it.


In the next article of this series, I will explain my vim setup including the plugin setup. Be prepared, it will be awesome to manage all you vim plugins with the Nix package manager!

Stay tuned! tags: #linux #nixos