updated nix setup

This commit is contained in:
Robin Appelman 2024-01-07 15:46:30 +01:00
commit 8ac57ca67e
11 changed files with 311 additions and 197 deletions

View file

@ -1,27 +0,0 @@
name: docker-build
on:
push:
branches:
- 'main'
- 'master'
jobs:
docker:
runs-on: ubuntu-20.04
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
push: true
tags: icewind1991/rss-webhook-trigger:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

74
.github/workflows/nix.yaml vendored Normal file
View file

@ -0,0 +1,74 @@
name: "Checks"
on:
pull_request:
push:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#check
clippy:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#clippy
msrv:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#msrv
build:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#rss-webhook-trigger
docker:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#docker
- name: Push image
if: github.ref == 'refs/heads/master'
run: |
skopeo copy --dest-creds="${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" "docker-archive:$(nix build .#docker --print-out-paths)" "docker://icewind1991/rss-webhook-trigger"

View file

@ -1,42 +0,0 @@
on: [push, pull_request]
name: CI
jobs:
check:
name: Check
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
command: check
build:
name: Build
runs-on: ubuntu-18.04
steps:
- name: musl-tools
run: |
sudo apt-get install musl-tools
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-musl
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
command: build
args: --release --target x86_64-unknown-linux-musl
- uses: actions/upload-artifact@v2
with:
name: rss-webhook-trigger
path: target/x86_64-unknown-linux-musl/release/rss-webhook-trigger

View file

@ -3,6 +3,7 @@ name = "rss-webhook-trigger"
version = "0.1.0" version = "0.1.0"
authors = ["Robin Appelman <robin@icewind.nl>"] authors = ["Robin Appelman <robin@icewind.nl>"]
edition = "2018" edition = "2018"
rust-version = "1.57.0"
[dependencies] [dependencies]
rss = "2.0.1" rss = "2.0.1"

View file

@ -1,20 +0,0 @@
FROM ekidd/rust-musl-builder AS build
COPY Cargo.toml Cargo.lock ./
# Build with a dummy main to pre-build dependencies
RUN mkdir src && \
echo "fn main(){}" > src/main.rs && \
cargo build --release && \
rm -r src
COPY src/* ./src/
RUN sudo chown -R rust:rust . && touch src/main.rs
RUN cargo build --release
FROM scratch
COPY --from=build /home/rust/src/target/x86_64-unknown-linux-musl/release/rss-webhook-trigger /
CMD ["/rss-webhook-trigger"]

16
docker.nix Normal file
View file

@ -0,0 +1,16 @@
{
dockerTools,
rss-webhook-trigger,
}:
dockerTools.buildLayeredImage {
name = "icewind1991/rss-webhook-trigger";
tag = "latest";
maxLayers = 5;
contents = [
rss-webhook-trigger
dockerTools.caCertificates
];
config = {
Cmd = ["rss-webhook-trigger"];
};
}

83
flake.lock generated
View file

@ -1,12 +1,15 @@
{ {
"nodes": { "nodes": {
"flake-utils": { "flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": { "locked": {
"lastModified": 1656928814, "lastModified": 1701680307,
"narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=", "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249", "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -17,14 +20,16 @@
}, },
"naersk": { "naersk": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "nixpkgs": [
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1655042882, "lastModified": 1698420672,
"narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=", "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
"owner": "nix-community", "owner": "nix-community",
"repo": "naersk", "repo": "naersk",
"rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f", "rev": "aeb58d5e8faead8980a807c840232697982d47b9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -35,25 +40,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 0, "lastModified": 1704420045,
"narHash": "sha256-URmf0O2cQ/3heg2DJOeLyU/JmfVMqG4X5t9crQXMaeY=", "narHash": "sha256-C36QmoJd5tdQ5R9MC1jM7fBkZW9zBUqbUCsgwS6j4QU=",
"path": "/nix/store/35wga4qglxf9rm8ki22ry3clwv1k2a7l-source", "owner": "NixOS",
"type": "path" "repo": "nixpkgs",
}, "rev": "c1be43e8e837b8dbee2b3665a007e761680f0c3d",
"original": { "type": "github"
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 0,
"narHash": "sha256-URmf0O2cQ/3heg2DJOeLyU/JmfVMqG4X5t9crQXMaeY=",
"path": "/nix/store/35wga4qglxf9rm8ki22ry3clwv1k2a7l-source",
"type": "path"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
@ -61,7 +57,46 @@
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"naersk": "naersk", "naersk": "naersk",
"nixpkgs": "nixpkgs_2" "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1704593904,
"narHash": "sha256-nDoXZDTRdgF3b4n3m011y99nYFewvOl9UpzFvP8Rb3c=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c36fd70a99decfa6e110c86f296a97613034a680",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
} }
} }
}, },

148
flake.nix
View file

@ -1,7 +1,12 @@
{ {
inputs = { inputs = {
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "nixpkgs/nixos-23.11";
naersk.url = "github:nix-community/naersk"; naersk.url = "github:nix-community/naersk";
naersk.inputs.nixpkgs.follows = "nixpkgs";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
rust-overlay.inputs.flake-utils.follows = "flake-utils";
}; };
outputs = { outputs = {
@ -9,104 +14,75 @@
nixpkgs, nixpkgs,
flake-utils, flake-utils,
naersk, naersk,
rust-overlay,
}: }:
flake-utils.lib.eachDefaultSystem ( flake-utils.lib.eachDefaultSystem (
system: let system: let
pkgs = nixpkgs.legacyPackages."${system}"; overlays = [
naersk-lib = naersk.lib."${system}"; (import rust-overlay)
in rec { (import ./overlay.nix)
# `nix build` ];
packages.rss-webhook-trigger = naersk-lib.buildPackage { pkgs = import nixpkgs {
pname = "rss-webhook-trigger"; inherit system overlays;
root = ./.;
}; };
defaultPackage = packages.rss-webhook-trigger;
defaultApp = packages.rss-webhook-trigger;
# `nix develop` inherit (pkgs) lib rust-bin callPackage;
devShell = pkgs.mkShell { inherit (builtins) fromTOML readFile;
nativeBuildInputs = with pkgs; [rustc cargo bacon cargo-edit cargo-outdated];
msrv = (fromTOML (readFile ./Cargo.toml)).package.rust-version;
toolchain = rust-bin.stable.latest.default;
msrvToolchain = rust-bin.stable."${msrv}".default;
naersk' = callPackage naersk {
rustc = toolchain;
cargo = toolchain;
};
msrvNaersk = callPackage naersk {
rustc = msrvToolchain;
cargo = msrvToolchain;
};
nearskOpt = {
pname = "rss-webhook-trigger";
root = pkgs.rss-webhook-trigger.src;
};
in rec {
packages = rec {
rss-webhook-trigger = pkgs.rss-webhook-trigger;
check = naersk'.buildPackage (nearskOpt
// {
mode = "check";
});
clippy = naersk'.buildPackage (nearskOpt
// {
mode = "clippy";
});
msrv = msrvNaersk.buildPackage (nearskOpt
// {
mode = "check";
});
docker = callPackage ./docker.nix {};
default = rss-webhook-trigger;
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [rustc cargo bacon cargo-edit cargo-outdated cargo-msrv];
}; };
} }
) )
// { // {
nixosModule = { overlays.default = import ./overlay.nix;
nixosModules.default = {
pkgs,
config, config,
lib, lib,
pkgs,
... ...
}: }: {
with lib; let imports = [./module.nix];
cfg = config.services.rss-webhook-trigger; config = lib.mkIf config.services.rss-webhook-trigger.enable {
format = pkgs.formats.toml {}; nixpkgs.overlays = [self.overlays.default];
configFile = format.generate "trigger.toml" { services.palantir.package = lib.mkDefault pkgs.rss-webhook-trigger;
feed = cfg.hooks;
};
in {
options.services.rss-webhook-trigger = {
enable = mkEnableOption "Enables the rss-webhook-trigger service";
hooks = mkOption rec {
description = "Hook configuration";
type = types.listOf (types.submodule {
options = {
feed = mkOption {
type = types.str;
description = "Source feed";
};
hook = mkOption {
type = types.str;
description = "hook url";
};
headers = mkOption {
type = types.attrs;
default = {};
description = "headers to send";
};
body = mkOption {
type = types.attrs;
default = {};
description = "body to send";
};
};
});
};
};
config = mkIf cfg.enable {
systemd.services."rss-webhook-trigger" = let
pkg = self.defaultPackage.${pkgs.system};
in {
wantedBy = ["multi-user.target"];
script = "${pkg}/bin/rss-webhook-trigger ${configFile}";
serviceConfig = {
Restart = "on-failure";
DynamicUser = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
PrivateDevices = true;
ProtectClock = true;
CapabilityBoundingSet = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
SystemCallArchitectures = "native";
ProtectKernelModules = true;
RestrictNamespaces = true;
MemoryDenyWriteExecute = true;
ProtectHostname = true;
LockPersonality = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "AF_INET AF_INET6";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "localhost link-local multicast";
};
};
};
}; };
};
}; };
} }

81
module.nix Normal file
View file

@ -0,0 +1,81 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.rss-webhook-trigger;
format = pkgs.formats.toml {};
configFile = format.generate "trigger.toml" {
feed = cfg.hooks;
};
in {
options.services.rss-webhook-trigger = {
enable = mkEnableOption "Enables the rss-webhook-trigger service";
hooks = mkOption rec {
description = "Hook configuration";
type = types.listOf (types.submodule {
options = {
feed = mkOption {
type = types.str;
description = "Source feed";
};
hook = mkOption {
type = types.str;
description = "hook url";
};
headers = mkOption {
type = types.attrs;
default = {};
description = "headers to send";
};
body = mkOption {
type = types.attrs;
default = {};
description = "body to send";
};
};
});
};
package = mkOption {
type = types.package;
description = "package to use";
};
};
config = mkIf cfg.enable {
systemd.services."rss-webhook-trigger" = {
wantedBy = ["multi-user.target"];
script = "${cfg.package}/bin/rss-webhook-trigger ${configFile}";
serviceConfig = {
Restart = "on-failure";
DynamicUser = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
PrivateDevices = true;
ProtectClock = true;
CapabilityBoundingSet = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
SystemCallArchitectures = "native";
ProtectKernelModules = true;
RestrictNamespaces = true;
MemoryDenyWriteExecute = true;
ProtectHostname = true;
LockPersonality = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "AF_INET AF_INET6";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "localhost link-local multicast";
};
};
};
}

3
overlay.nix Normal file
View file

@ -0,0 +1,3 @@
final: prev: {
rss-webhook-trigger = final.callPackage ./package.nix {};
}

17
package.nix Normal file
View file

@ -0,0 +1,17 @@
{
rustPlatform,
lib,
}: let
inherit (lib.sources) sourceByRegex;
src = sourceByRegex ./. ["Cargo.*" "(src)(/.*)?"];
in
rustPlatform.buildRustPackage rec {
name = "rss-webhook-trigger";
version = "0.1.0";
inherit src;
cargoLock = {
lockFile = ./Cargo.lock;
};
}