dravetech.com

Managing your computer declaratively nix rules

28 November 2020    tools automation 

Recently I have been nagging people about nix and home-manager and I always get the same comment back “looks cool, how do I get started?”. Truth be told, the setup has a bit of a steep learning curve so figured I’d write a short blog post to point people in the right direction.

Before we begin, let me explain what the point of these tools are; to declaratively manage your environment/laptop/server. With this you should be able to declare your environment (required software, configurations, etc) and simply execute a command to let nix do its magic and keep your environment ready to use. In my personal case I use nixos (a linux distro with nix at its core) to manage my raspberry pi (which is out of the scope of this post) and nix-darwin and home-manager to manage both my personal and corporate laptops. Thanks to nix I can maintain both computers effortlessly, and, in case of having to reinstall any, have them up to speed in less than an hour after the OS is done installing.

If you are still interested, you need three pieces to manage macos:

  1. nix itself, which you can install following the instructions here
  2. nix-darwin, which you can install following these other instructions
  3. add home-manager as a “nix channel” as instructed here

Ok, now that you are ready, let’s try it out. We are going to do the following:

  1. Configure zsh as our shell and to make use of tools like ohmyzsh, thefuck, fzf and jump
  2. Configure git declaratively
  3. Configure the macos dock to hide automatically
  4. Configure a schedule job to clean docker (I personally manage docker outside of nix using docker desktop for mac)
  5. Install some python tools like virtualenvwrapper and poetry
  6. Install and configure golang

Start by editing the file .nixpkgs/darwin-configuration.nix and adding (don’t forget to change the user accordingly):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{ config, pkgs, ... }:

{
  imports = [
    <home-manager/nix-darwin>
    ./git.nix
    ./zsh.nix
  ];

  # List packages installed in system profile. To search by name, run:
  # $ nix-env -qaP | grep wget
  environment.systemPackages = [
  ];

  # Auto upgrade nix package and the daemon service.
  # services.nix-daemon.enable = true;
  nix.package = pkgs.nix;

  programs.zsh.enable = true;

  # Used for backwards compatibility, please read the changelog before changing.
  # $ darwin-rebuild changelog
  system.stateVersion = 4;

  # hide the dock automatically
  system.defaults = {
    dock = {
      autohide = true;
      orientation = "bottom";
    };
  };

  # keeping docker clean
  launchd.user.agents.dockerclean = {
    script ="/usr/local/bin/docker system prune --volumes -f";

    serviceConfig.StartCalendarInterval = [
      { Minute = 20; Hour = 11;}
    ];

  };

  home-manager.useUserPackages = true;

  home-manager.users.dbarroso = { pkgs, ... }: {
    home.packages = with pkgs; [
      jump
      poetry
      python38Packages.virtualenv
      python38Packages.virtualenvwrapper
      thefuck
      silver-searcher
    ];

    programs.fzf = {
      enable = true;
    };

    programs.go = {
      enable = true;
    };

  };

}

In addition, you should edit ~/.nixpkgs/git.nix and enter something similar to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{ config, pkgs, ... }:

{
  # my global gitignore
  home-manager.users.dbarroso.home.file."gitignore" = {
    text = ''
    tags
    .DS_Store
    '';
    target = ".gitignore";
  };

  home-manager.users.dbarroso.programs.git = {
    enable = true;
    userName = "David Barroso";
    userEmail = "fake@email.com";

    extraConfig = {
      core = {
        excludesFile = "~/.gitignore";
      };
      pull = {
        rebase = false;
      };
      url = {
        "ssh://git@github.com" = {
          insteadOf = "https://github.com";
        };
      };

    };
  };

}

And finally, edit ~/.nixpkgs/zsh.nix and add:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{ config, pkgs, ... }:

{
  home-manager.users.dbarroso.programs.zsh = {
    enable = true;

    enableAutosuggestions = true;
    enableCompletion = true;

    oh-my-zsh = {
      enable = true;
      theme = "robbyrussell";

      plugins = [
        "dash"
        "docker"
        "docker-compose"
        "git"
        "golang"
      ];
    };

    initExtra = ''
      . virtualenvwrapper.sh

      eval "$(jump shell)"

      eval $(thefuck --alias)

      if [ -e /Users/dbarroso/.nix-profile/etc/profile.d/nix.sh ]; then . /Users/dbarroso/.nix-profile/etc/profile.d/nix.sh; fi # added by Nix installer
    '';
  };

}

Once you have your config ready you just have to execute:

1
darwin-rebuild switch

And your system should be ready :)

For reference, other stuff I manage with this includes things like:

  1. alacritty
  2. gpg + yubikey
  3. tmux
  4. nvim
  5. weechat
  6. ssh configuration
  7. many other tools like the rust toolchain, google cloud sdk, etc…

I know this was sparse on details but hopefully this was enough to get you interested and point you in the right direction.


napalm-yang has been abandoned :(

15 May 2019    networking automation 

It’s with sadness that I announce that napalm-yang is officially abandoned. It’s a strange feeling to abandon a project, specially one that some people may be relying on, but that’s always a risk in the opensource world. If you are a napalm-yang user or were planning to use it there are two paths for you right now:

  1. Fork the project. I encourage you to do so if you feel that’s the best course of action for you. I will try to support you as best as possible and direct new and existing users to your fork.
  2. Migrate to yangify and other related projects that will be released soon.

My recommended path would be to go yangify for a few reasons. First, it replaces pyangbind with yangson. This brings some memory and CPU efficiencies and makes the project simpler to maintain as there is no need for bindings. This doesn’t mean you can’t use bindings, it just makes it optional.

More importantly, it replaces the custom DSL with a python framework. This brings a list of advantages:

  1. Less code to maintain as there is no need to translate the DSL to actual python code
  2. Orders of magnitude faster as there is no need to go back and forth between the DSL and the python code
  3. More flexibility as there is so much you can express with a DSL.

Don’t hesitate to contact me directly if you are concerned about this announcement or if you want help migrating to yangify or forking napalm-yang.


Global Routing as a Service GRAAS

07 December 2018    networking automation 

A few months back I gave a talk at PLNOG21 about how we manage our global internet presence at Fastly. You can find the recording of the talk here


Network telemetry from SNMP to prometheus

22 May 2018    monitoring networking 

Whether you just don’t like SNMP or you want to leverage the same tooling for monitoring and alerting as the rest of your organization, this “tutorial” has you covered. What we are going to do is see how we can monitor our network infrastructure with prometheus and grafana.

In this blogpost we are going to see how to build a webapp using flask+nornir that gathers metrics from the network and presents it via a web application. Then we will scrape that web application with prometheus to store those metrics and finally we will see how we can present those metrics with grafana. In summary, you will learn how to replace your old-fashioned SNMP monitoring system with a next-generation-12-factor-app-compliant-telemetry-system.

Continue reading on github


GoBGP grpc code examples

18 April 2017    bgp automation networking 

For those that haven’t heard about it yet, GoBGP is, as they say “an open source BGP implementation designed from scratch for modern environment and implemented in a modern programming language, the Go Programming Language”.

To me, the most interesting part of GoBGP is that it uses a grpc interface to interact with the daemon and anything that can be done via its configuration file and/or CLI can be done via this interface. As a matter of fact, the CLI actually uses this interface to retrieve data and configure things.