Git mirroring, systemd and NixOS

For the past few years I have been collecting contributions to multiple projects on multiple platforms such as GitHub, GitLab, self-hosted Gitea instances and so on. It’s rather boring to go to a website and see the source code there… Then I thought to myself: “Why not write about a made up need I don’t have just to learn something new?”.

So, the idea here was to mirror those repositories into my sourcehut account (although this should work for any remote repository). For this we will use a NixOS system and systemd timers. The idea is dead simple, we clone the repositories and push them to our desired remote.

Configuring the repository

This step is pretty easy and can be done in two steps:

  1. Clone the repository
$ git clone --mirror https://git.com/repo
  1. Configure the remote as to ensure that we will only push to the desired remote.
$ cd repo
$ git remote set-url --push origin https://remote.com/repo-mirror

systemd to the rescue

We have our repository but we are still missing an important step that is to keep pushing new changes to our mirror.

NixOS has a pretty good declarative way of declaring systemd services and timers that we can take advantage of here. The idea is to have a script being ran in our diretory through a systemd service that will be invoked by a systemd timer hourly.

The script

There’s nothing novel here. This script will iterate over the directories inside the WorkingDirectory, fetch updates and then push it to our mirror.

let
  gitmirrorScript = pkgs.writeShellScriptBin "gitmirror" ''
    for d in */ ; do
      git -C "$d" fetch -p origin
      git -C "$d" push --mirror
    done
  '';
in

The service and timer

The service is rather simple too, we pass our repository’s directory through the WorkingDirectory value and set the gitmirror service as the unit to be invoked by our timer. Note, however, that we added git and openssh to the path. Your root user should be able to authenticate on boths repos with its ssh key.

{
  systemd.services.gitmirror = {
    enable = true;
    description = "Git mirror service";
    after = [ "network.target" ];
    path = with pkgs; [ git openssh ];
    serviceConfig = {
      Type="oneshot";
      WorkingDirectory = "/home/glorifiedgluer/repo";
      ExecStart = "${gitmirrorScript}/bin/gitmirror";
    };
    wantedBy = [ "multi-user.target" ];
  };

  systemd.timers.gitmirror = {
    description = "Git mirror timer";
    timerConfig = {
      OnCalendar = "hourly";
      Unit = "gitmirror.service";
    };
    wantedBy = [ "timers.target" ];
  };
}

Articles from blogs I follow around the net

The four tenets of SOA revisited

Twenty years after. In the January 2004 issue of MSDN Magazine you can find an article by Don Box titled A Guide to Developing and Running Connected Systems with Indigo. Buried within the (now dated) discussion of the technology…

via ploeh blog March 4, 2024

Building a demo of the Bleichenbacher RSA attack in Rust

Recently while reading Real-World Cryptography, I got nerd sniped1 by the mention of Bleichenbacher's attack on RSA. This is cool, how does it work? I had to understand, and to understand something, I usually have to build it. Well, friends, that is what…

via ntietz.com blog March 4, 2024

How to unbreak Dolphin on SteamOS after the QT6 update

A recent update to Dolphin made it switch to QT6. This makes it crash with this error or something like it: dolphin-emu: symbol lookup error: dolphin-emu: undefined symbol: _Zls6QDebugRK11QDockWidget, version Qt_6 This is fix…

via Xe Iaso's blog March 3, 2024

Generated by openring