1
0
Fork 0
mirror of https://codeberg.org/icewind/shelve.git synced 2026-06-03 12:04:09 +02:00

new nix setup

This commit is contained in:
Robin Appelman 2024-01-06 22:47:16 +01:00
commit 6c9cb7ac7d
9 changed files with 367 additions and 163 deletions

View file

@ -4,39 +4,88 @@ name: Continuous integration
jobs: jobs:
check: check:
name: Check runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1 - uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with: with:
profile: minimal name: ci
toolchain: stable instance: https://cache.icewind.me
override: true authToken: '${{ secrets.ATTIC_TOKEN }}'
- uses: Swatinem/rust-cache@v1 - run: nix build .#check
- uses: actions-rs/cargo@v1
clippy:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with: with:
command: check 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
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- id: set-matrix
run: echo "matrix=$(nix eval --json ".#matrix.x86_64-linux")" | tee $GITHUB_OUTPUT
build: build:
name: Build Binaries runs-on: ubuntu-latest
runs-on: ubuntu-20.04 needs: [check, matrix]
strategy:
fail-fast: false
matrix: ${{fromJson(needs.matrix.outputs.matrix)}}
steps: steps:
- name: musl-tools - 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 .#${{ matrix.target }}
- uses: actions/upload-artifact@v3
with:
name: shelve-${{ matrix.target }}
path: result/bin/shelve${{ matrix.artifactSuffix }}
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: | run: |
sudo apt-get install musl-tools skopeo copy --dest-creds="${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" "docker-archive:$(nix build .#docker --print-out-paths)" "docker://icewind1991/shelve"
- 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: shelve
path: target/x86_64-unknown-linux-musl/release/shelve

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/shelve:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View file

@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Robin Appelman <robin@icewind.nl>"] authors = ["Robin Appelman <robin@icewind.nl>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
rust-version = "1.56.0"
[dependencies] [dependencies]
rocket = "0.5.0-rc.1" rocket = "0.5.0-rc.1"

23
docker.nix Normal file
View file

@ -0,0 +1,23 @@
{
dockerTools,
shelve,
}:
dockerTools.buildLayeredImage {
name = "icewind1991/shelve";
tag = "latest";
maxLayers = 5;
contents = [
shelve
dockerTools.caCertificates
];
config = {
Cmd = ["shelve"];
ExposedPorts = {
"80/tcp" = {};
};
Env = [
"ROCKET_ADDRESS=0.0.0.0"
"ROCKET_PORT=80"
];
};
}

109
flake.lock generated
View file

@ -1,12 +1,38 @@
{ {
"nodes": { "nodes": {
"flake-utils": { "cross-naersk": {
"inputs": {
"naersk": [
"naersk"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1656928814, "lastModified": 1689107909,
"narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=", "narHash": "sha256-fb+zxf7AWesECHx1foXOM3NcKHLrdeXzGb6s2AhT6pE=",
"owner": "icewind1991",
"repo": "cross-naersk",
"rev": "51de54599de569e6faa2ee33dd659c5c028d9911",
"type": "github"
},
"original": {
"owner": "icewind1991",
"repo": "cross-naersk",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1701680307,
"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 +43,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,33 +63,64 @@
}, },
"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"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"cross-naersk": "cross-naersk",
"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": 1704507282,
"narHash": "sha256-PDfS8fj40mm2QWpbd/aiocgwcI/WHzqLKERRJkoEvXU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "a127cccf7943beae944953963ba118d643299c3b",
"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"
} }
} }
}, },

175
flake.nix
View file

@ -1,7 +1,15 @@
{ {
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-23.11";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
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";
cross-naersk.url = "github:icewind1991/cross-naersk";
cross-naersk.inputs.nixpkgs.follows = "nixpkgs";
cross-naersk.inputs.naersk.follows = "naersk";
}; };
outputs = { outputs = {
@ -9,104 +17,91 @@
nixpkgs, nixpkgs,
flake-utils, flake-utils,
naersk, naersk,
rust-overlay,
cross-naersk,
}: }:
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.shelve = naersk-lib.buildPackage { pkgs = (import nixpkgs) {
pname = "shelve"; inherit system overlays;
root = ./.;
}; };
defaultPackage = packages.shelve; inherit (pkgs) lib callPackage rust-bin mkShell;
defaultApp = packages.shelve; inherit (lib.sources) sourceByRegex;
inherit (builtins) fromTOML readFile map;
# `nix develop` msrv = (fromTOML (readFile ./Cargo.toml)).package.rust-version;
devShell = pkgs.mkShell { toolchain = rust-bin.stable.latest.default;
nativeBuildInputs = with pkgs; [rustc cargo bacon]; msrvToolchain = rust-bin.stable."${msrv}".default;
naersk' = callPackage naersk {
rustc = toolchain;
cargo = toolchain;
};
msrvNaersk = callPackage naersk {
rustc = msrvToolchain;
cargo = msrvToolchain;
};
cross-naersk' = pkgs.callPackage cross-naersk {inherit naersk;};
buildMatrix = targets: {
include =
map (target: {
inherit target;
artifactSuffix = cross-naersk'.execSufficForTarget target;
})
targets;
};
hostTarget = pkgs.hostPlatform.config;
targets = [
"x86_64-unknown-linux-musl"
"x86_64-pc-windows-gnu"
hostTarget
];
releaseTargets = lib.lists.remove hostTarget targets;
src = sourceByRegex ./. ["Cargo.*" "(src|templates)(/.*)?"];
nearskOpt = {
pname = "shelve";
root = src;
};
in rec {
packages =
lib.attrsets.genAttrs targets (target:
(cross-naersk'.buildPackage target) nearskOpt)
// {
shelve = pkgs.shelve;
check = naersk'.buildPackage (nearskOpt
// {
mode = "check";
});
clippy = naersk'.buildPackage (nearskOpt
// {
mode = "clippy";
});
msrv = msrvNaersk.buildPackage (nearskOpt
// {
mode = "check";
});
docker = callPackage ./docker.nix {};
default = pkgs.shelve;
};
apps.default = packages.default;
matrix = buildMatrix targets;
releaseMatrix = buildMatrix releaseTargets;
devShells.default = mkShell {
nativeBuildInputs = with pkgs; [toolchain bacon cargo-msrv];
}; };
} }
) )
// { // {
nixosModule = { overlays.default = import ./overlay.nix;
config, nixosModules.default = import ./module.nix;
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.shelve;
in {
options.services.shelve = {
enable = mkEnableOption "Enables the shelve service";
port = mkOption rec {
type = types.int;
example = 8080;
description = "The port to listen on";
};
bindAddress = mkOption {
type = types.str;
default = "0.0.0.0";
description = "Address to listen on";
};
tokens = mkOption {
type = types.listOf types.str;
default = [];
example = ["foo" "bar"];
description = "upload tokens";
};
basedir = mkOption {
type = types.str;
description = "data base directory";
};
openPort = mkOption {
type = types.bool;
default = false;
example = true;
description = "open port";
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = lib.optional cfg.openPort cfg.port;
users.groups.shelve = {};
users.users.shelve = {
isSystemUser = true;
group = "shelve";
};
systemd.services.shelve = let
pkg = self.defaultPackage.${pkgs.system};
in {
wantedBy = ["multi-user.target"];
environment = {
ROCKET_PORT = toString cfg.port;
ROCKET_ADDRESS = cfg.bindAddress;
BASEDIR = cfg.basedir;
TOKENS = concatStringsSep "," cfg.tokens;
};
script = "${pkg}/bin/shelve";
serviceConfig = {
Restart = "on-failure";
User = "shelve";
PrivateTmp = true;
ProtectSystem = "full";
ProtectHome = true;
NoNewPrivileges = true;
ReadWritePaths = cfg.basedir;
NoExecPaths = cfg.basedir;
};
};
};
};
}; };
} }

83
module.nix Normal file
View file

@ -0,0 +1,83 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.shelve;
in {
options.services.shelve = {
enable = mkEnableOption "Enables the shelve service";
port = mkOption rec {
type = types.int;
example = 8080;
description = "The port to listen on";
};
bindAddress = mkOption {
type = types.str;
default = "0.0.0.0";
description = "Address to listen on";
};
tokens = mkOption {
type = types.listOf types.str;
default = [];
example = ["foo" "bar"];
description = "upload tokens";
};
basedir = mkOption {
type = types.str;
description = "data base directory";
};
package = mkOption {
default = pkgs.shelve;
type = types.package;
defaultText = literalExpression "pkgs.shelve";
description = "package to use";
};
openPort = mkOption {
type = types.bool;
default = false;
example = true;
description = "open port";
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = lib.optional cfg.openPort cfg.port;
users.groups.shelve = {};
users.users.shelve = {
isSystemUser = true;
group = "shelve";
};
systemd.services.shelve = {
wantedBy = ["multi-user.target"];
environment = {
ROCKET_PORT = toString cfg.port;
ROCKET_ADDRESS = cfg.bindAddress;
BASEDIR = cfg.basedir;
TOKENS = concatStringsSep "," cfg.tokens;
};
script = "${cfg.package}/bin/shelve";
serviceConfig = {
Restart = "on-failure";
User = "shelve";
PrivateTmp = true;
ProtectSystem = "full";
ProtectHome = true;
NoNewPrivileges = true;
ReadWritePaths = cfg.basedir;
NoExecPaths = cfg.basedir;
};
};
};
}

3
overlay.nix Normal file
View file

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

18
package.nix Normal file
View file

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