home

My NixOS systems configurations.
Log | Files | Refs | LICENSE

containers-image-mirroring.nix (2307B)


      1 { config, lib, pkgs, ... }:
      2 
      3 let
      4   inherit (lib) mkEnableOption mkOption mkIf types;
      5   cfg = config.modules.dev.containers.image-mirroring;
      6   settingsFormat = pkgs.formats.yaml { };
      7   settingsFile = settingsFormat.generate "sync.yaml" cfg.settings;
      8 in
      9 {
     10   ##### interface
     11   options = {
     12     modules.dev.containers.image-mirroring = {
     13       enable = mkEnableOption "Enable container image mirroring service";
     14       targets = mkOption {
     15         type = types.listOf types.str;
     16         example = [ "quay.io/vdemeest" "ghcr.io/vdemeester" ];
     17         description = lib.mdDoc ''
     18           A list of targets to sync images to. It will use the same
     19           sync configuration to push on all.
     20         '';
     21       };
     22       settings = mkOption {
     23         type = settingsFormat.type;
     24         default = { };
     25         example = {
     26           "docker.io" = {
     27             "vdemeester/foo" = [ "latest" "bar" ];
     28           };
     29           "quay.io" = {
     30             "buildah/stable" = [ "latest" ];
     31           };
     32         };
     33         description = lib.mdDoc ''
     34           Configuration of the image to sync, using skopeo-sync.
     35           See skopeo-sync(1) for the content. 
     36         '';
     37       };
     38     };
     39   };
     40   ##### implementation
     41   config = mkIf cfg.enable {
     42     systemd.services.container-image-mirroring = {
     43       description = "Synchronize docker images to a set of targets";
     44       requires = [ "network-online.target" ];
     45 
     46       restartIfChanged = false;
     47       unitConfig.X-StopOnRemoval = false;
     48 
     49       serviceConfig = {
     50         Type = "oneshot";
     51         User = "vincent";
     52         OnFailure = "status-email-root@%.service";
     53       };
     54 
     55       path = with pkgs; [ skopeo ];
     56       # ./scripts/docker.mirroring.script.sh;
     57       script = ''
     58         BUILDTMPDIR=$(mktemp -d)
     59         trap 'rm -rf -- "$BUILDTMPDIR"' EXIT
     60 
     61 
     62         # Pull to dir first
     63         skopeo sync --preserve-digests --src yaml --dest dir \
     64                ${settingsFile} \
     65                $BUILDTMPDIR
     66 
     67         # Push to targets
     68         for target in ${lib.strings.concatStringsSep " " cfg.targets}; do
     69             skopeo sync --preserve-digests --src dir --dest docker \
     70                    $BUILDTMPDIR \
     71                    $target
     72         done
     73       '';
     74 
     75       after = [ "network-online.target" ];
     76       # Make it configurable ?
     77       startAt = "weekly";
     78     };
     79   };
     80 }