flake reorg

This commit is contained in:
Robin Appelman 2024-01-14 17:04:48 +01:00
commit c0437522d7
12 changed files with 210 additions and 217 deletions

View file

@ -1,2 +0,0 @@
.env
target

34
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,34 @@
on: [push, pull_request]
name: Continuous integration
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v25
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build
docker:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: cachix/install-nix-action@v25
- 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/tasproxy"

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

View file

@ -1,42 +0,0 @@
on: [push, pull_request]
name: CI
jobs:
check:
name: Check
runs-on: ubuntu-latest
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 Binaries
runs-on: ubuntu-latest
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: tasproxy
path: target/x86_64-unknown-linux-musl/release/tasproxy

View file

@ -1,21 +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/tasproxy /
EXPOSE 80
CMD ["/tasproxy"]

View file

@ -10,7 +10,9 @@ Remembering what ip addresses all of your tasmota devices is a pain.
Ensure your tasmota devices are connected to an MQTT server with the following "Full Topic": Ensure your tasmota devices are connected to an MQTT server with the following "Full Topic":
%prefix%/%topic%/%hostname%/ %prefix%/%topic%/
And the "Topic" set to the desired name for the device.
Run the binary with the following environment variables Run the binary with the following environment variables
@ -26,4 +28,4 @@ Setup dns/hosts/etc to point *.example.com to the server running this binary
The proxy server will use MQTT to discover and gather the ip addresses of your tasmota devices. The proxy server will use MQTT to discover and gather the ip addresses of your tasmota devices.
Any request made to `%hostname%.example.com` will be proxied to the tasmota device with the corresponding hostname. Any request made to `%hostname%.example.com` will be proxied to the tasmota device with the corresponding topic.

19
docker.nix Normal file
View file

@ -0,0 +1,19 @@
{
dockerTools,
tasproxy,
}:
dockerTools.buildLayeredImage {
name = "icewind1991/tasproxy";
tag = "latest";
maxLayers = 5;
contents = [
tasproxy
dockerTools.caCertificates
];
config = {
Cmd = ["tasproxy"];
ExposedPorts = {
"80/tcp" = {};
};
};
}

72
flake.lock generated
View file

@ -1,67 +1,57 @@
{ {
"nodes": { "nodes": {
"flake-utils": { "flake-utils": {
"locked": {
"lastModified": 1656928814,
"narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"naersk": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1655042882, "lastModified": 1701680307,
"narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=", "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "nix-community", "owner": "numtide",
"repo": "naersk", "repo": "flake-utils",
"rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f", "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "numtide",
"repo": "naersk", "repo": "flake-utils",
"type": "github" "type": "github"
} }
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 0, "lastModified": 1705183652,
"narHash": "sha256-WbZKCf6g4+dljZ6Z866SGZzNA+WWjXt4Lc7td4zsRkw=", "narHash": "sha256-rnfkyUH0x72oHfiSDhuCHDHg3gFgF+lF8zkkg5Zihsw=",
"path": "/nix/store/vavqvhqw8x42kqb1m3wkcys65jvvnl5i-source", "owner": "NixOS",
"type": "path" "repo": "nixpkgs",
}, "rev": "428544ae95eec077c7f823b422afae5f174dee4b",
"original": { "type": "github"
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 0,
"narHash": "sha256-WbZKCf6g4+dljZ6Z866SGZzNA+WWjXt4Lc7td4zsRkw=",
"path": "/nix/store/vavqvhqw8x42kqb1m3wkcys65jvvnl5i-source",
"type": "path"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"naersk": "naersk", "nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs_2" }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
} }
} }
}, },

105
flake.nix
View file

@ -1,109 +1,46 @@
{ {
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";
}; };
outputs = { outputs = {
self, self,
nixpkgs, nixpkgs,
flake-utils, flake-utils,
naersk,
}: }:
flake-utils.lib.eachDefaultSystem ( flake-utils.lib.eachDefaultSystem (
system: let system: let
pkgs = nixpkgs.legacyPackages."${system}"; overlays = [
naersk-lib = naersk.lib."${system}"; (import ./overlay.nix)
];
pkgs = (import nixpkgs) {
inherit system overlays;
};
in rec { in rec {
# `nix build` packages = rec {
packages.tasproxy = naersk-lib.buildPackage { tasproxy = pkgs.tasproxy;
pname = "tasproxy"; docker = pkgs.callPackage ./docker.nix {};
root = ./.; default = tasproxy;
}; };
defaultPackage = packages.tasproxy;
defaultApp = packages.tasproxy;
# `nix develop`
devShell = pkgs.mkShell { devShell = pkgs.mkShell {
nativeBuildInputs = with pkgs; [rustc cargo bacon cargo-edit cargo-outdated]; nativeBuildInputs = with pkgs; [rustc cargo bacon cargo-edit cargo-outdated clippy];
}; };
} }
) )
// { // {
nixosModule = { overlays.default = import ./overlay.nix;
nixosModules.default = {
pkgs,
config, config,
lib, lib,
pkgs,
... ...
}: }: {
with lib; let imports = [./module.nix];
cfg = config.services.tasproxy; config = lib.mkIf config.services.tasproxy.enable {
in { nixpkgs.overlays = [self.overlays.default];
options.services.tasproxy = { services.tasproxy.package = lib.mkDefault pkgs.tasproxy;
enable = mkEnableOption "Log archiver";
port = mkOption {
type = types.int;
default = 3000;
description = "port to listen on";
};
mqttCredentailsFile = mkOption {
type = types.str;
description = "file containg MQTT_HOSTNAME, MQTT_USERNAME and MQTT_PASSWORD variables";
};
enableUnixSocket = mkOption {
type = types.bool;
default = false;
description = "listen to a unix socket instead of TCP";
};
};
config = mkIf cfg.enable {
systemd.services."tasproxy" = let
pkg = self.defaultPackage.${pkgs.system};
in {
wantedBy = ["multi-user.target"];
script = "${pkg}/bin/tasproxy";
environment = if cfg.enableUnixSocket then {
SOCKET = "/run/tasproxy/tasproxy.sock";
} else {
PORT = cfg.port;
};
serviceConfig = {
EnvironmentFile = cfg.mqttCredentailsFile;
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 AF_UNIX";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "multicast";
PrivateUsers = true;
ProcSubset = "pid";
RuntimeDirectory = "tasproxy";
RestrictSUIDSGID = true;
};
};
};
}; };
};
}; };
} }

82
module.nix Normal file
View file

@ -0,0 +1,82 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.tasproxy;
in {
options.services.tasproxy = {
enable = mkEnableOption "Log archiver";
port = mkOption {
type = types.int;
default = 3000;
description = "port to listen on";
};
mqttCredentailsFile = mkOption {
type = types.str;
description = "file containg MQTT_HOSTNAME, MQTT_USERNAME and MQTT_PASSWORD variables";
};
enableUnixSocket = mkOption {
type = types.bool;
default = false;
description = "listen to a unix socket instead of TCP";
};
package = mkOption {
type = types.package;
defaultText = literalExpression "pkgs.tasproxy";
description = "package to use";
};
};
config = mkIf cfg.enable {
systemd.services."tasproxy" = {
wantedBy = ["multi-user.target"];
environment =
if cfg.enableUnixSocket
then {
SOCKET = "/run/tasproxy/tasproxy.sock";
}
else {
PORT = cfg.port;
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/tasproxy";
EnvironmentFile = cfg.mqttCredentailsFile;
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 AF_UNIX";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "multicast";
PrivateUsers = true;
ProcSubset = "pid";
RuntimeDirectory = "tasproxy";
RestrictSUIDSGID = true;
};
};
};
}

3
overlay.nix Normal file
View file

@ -0,0 +1,3 @@
final: prev: {
tasproxy = 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)(/.*)?"];
in
rustPlatform.buildRustPackage rec {
pname = "tasproxy";
version = "0.1.0";
inherit src;
cargoLock = {
lockFile = ./Cargo.lock;
};
}