From a37a5e5752a2b42f57a813893704e8548c093f94 Mon Sep 17 00:00:00 2001 From: ppom Date: Wed, 11 Feb 2026 12:00:00 +0100 Subject: [PATCH] release v2.3.0 - cross-rs project doesn't compile anymore: switching to debian12-amd64 only binary release - package virtual plugin in reaction .deb - package ipset plugin in separate .deb with its required libipset-dev dependency --- Cargo.lock | 6 +- Cargo.toml | 3 +- Dockerfile | 11 ++ packaging/Makefile | 8 +- plugins/reaction-plugin-ipset/Cargo.toml | 16 ++- plugins/reaction-plugin-virtual/Cargo.toml | 2 +- release.py | 159 +++++++++++++-------- 7 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 Dockerfile diff --git a/Cargo.lock b/Cargo.lock index dac6c60..f5b71b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2828,7 +2828,7 @@ dependencies = [ [[package]] name = "reaction" -version = "2.2.1" +version = "2.3.0" dependencies = [ "assert_cmd", "assert_fs", @@ -2889,7 +2889,7 @@ dependencies = [ [[package]] name = "reaction-plugin-ipset" -version = "0.1.0" +version = "1.0.0" dependencies = [ "ipset", "reaction-plugin", @@ -2901,7 +2901,7 @@ dependencies = [ [[package]] name = "reaction-plugin-virtual" -version = "0.1.0" +version = "1.0.0" dependencies = [ "reaction-plugin", "remoc", diff --git a/Cargo.toml b/Cargo.toml index 5f626de..dd537aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reaction" -version = "2.2.1" +version = "2.3.0" edition = "2024" authors = ["ppom "] license = "AGPL-3.0" @@ -22,6 +22,7 @@ systemd-units = { enable = false } assets = [ # Executables [ "target/release/reaction", "/usr/bin/reaction", "755" ], + [ "target/release/reaction-plugin-virtual", "/usr/bin/reaction-plugin-virtual", "755" ], # Man pages [ "target/release/reaction*.1", "/usr/share/man/man1/", "644" ], # Shell completions diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1c5d54e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# This Dockerfile permits to build reaction and its plugins + +# Use debian old-stable, so that it runs on both old-stable and stable +FROM rust:bookworm + +RUN apt update && apt install -y \ + clang \ + libipset-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /reaction diff --git a/packaging/Makefile b/packaging/Makefile index ead1735..ac1a064 100644 --- a/packaging/Makefile +++ b/packaging/Makefile @@ -4,15 +4,21 @@ MANDIR = $(PREFIX)/share/man/man1 SYSTEMDDIR ?= /etc/systemd install: - install -Dm755 reaction $(DESTDIR)$(BINDIR) + install -Dm755 reaction $(DESTDIR)$(BINDIR) + install -Dm755 reaction-plugin-virtual $(DESTDIR)$(BINDIR) install -Dm644 reaction*.1 -t $(DESTDIR)$(MANDIR)/ install -Dm644 reaction.bash $(DESTDIR)$(PREFIX)/share/bash-completion/completions/reaction install -Dm644 reaction.fish $(DESTDIR)$(PREFIX)/share/fish/vendor_completions.d/reaction.fish install -Dm644 _reaction $(DESTDIR)$(PREFIX)/share/zsh/vendor-completions/_reaction install -Dm644 reaction.service $(SYSTEMDDIR)/system/reaction.service +install-ipset: + install -Dm755 reaction-plugin-ipset $(DESTDIR)$(BINDIR) + remove: rm -f $(DESTDIR)$(BINDIR)/bin/reaction + rm -f $(DESTDIR)$(BINDIR)/bin/reaction-plugin-virtual + rm -f $(DESTDIR)$(BINDIR)/bin/reaction-plugin-ipset rm -f $(DESTDIR)$(MANDIR)/reaction*.1 rm -f $(DESTDIR)$(PREFIX)/share/bash-completion/completions/reaction rm -f $(DESTDIR)$(PREFIX)/share/fish/vendor_completions.d/reaction.fish diff --git a/plugins/reaction-plugin-ipset/Cargo.toml b/plugins/reaction-plugin-ipset/Cargo.toml index e6247e2..b709176 100644 --- a/plugins/reaction-plugin-ipset/Cargo.toml +++ b/plugins/reaction-plugin-ipset/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "reaction-plugin-ipset" -version = "0.1.0" +description = "ipset plugin for reaction" +version = "1.0.0" edition = "2024" +authors = ["ppom "] +license = "AGPL-3.0" +homepage = "https://reaction.ppom.me" +repository = "https://framagit.org/ppom/reaction" +keywords = ["security", "sysadmin", "fail2ban", "logs", "monitoring"] +default-run = "reaction-plugin-ipset" [dependencies] tokio = { workspace = true, features = ["rt-multi-thread"] } @@ -10,3 +17,10 @@ reaction-plugin.path = "../reaction-plugin" serde.workspace = true serde_json.workspace = true ipset = "0.9.0" + +[package.metadata.deb] +section = "net" +assets = [ + [ "target/release/reaction-plugin-ipset", "/usr/bin/reaction-plugin-ipset", "755" ], +] +depends = ["libipset-dev", "reaction"] diff --git a/plugins/reaction-plugin-virtual/Cargo.toml b/plugins/reaction-plugin-virtual/Cargo.toml index 46e3430..f6a1fca 100644 --- a/plugins/reaction-plugin-virtual/Cargo.toml +++ b/plugins/reaction-plugin-virtual/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reaction-plugin-virtual" -version = "0.1.0" +version = "1.0.0" edition = "2024" [dependencies] diff --git a/release.py b/release.py index 06c5977..5fa870c 100644 --- a/release.py +++ b/release.py @@ -1,11 +1,11 @@ #!/usr/bin/env nix-shell -#!nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ requests ])" -p debian-devscripts git minisign cargo-cross rustup cargo-deb +#!nix-shell -i python3 -p "python3.withPackages (ps: with ps; [ requests ])" -p debian-devscripts git minisign docker cargo-deb import argparse import http.client import json import os -import subprocess import shutil +import subprocess import sys import tempfile @@ -56,14 +56,14 @@ def main(): print("exiting.") sys.exit(1) + # Minisign password + cmd = subprocess.run(["rbw", "get", "minisign"], capture_output=True, text=True) + minisign_password = cmd.stdout + if args.publish: # Git push run_command(["git", "push", "--tags"]) - # Minisign password - cmd = subprocess.run(["rbw", "get", "minisign"], capture_output=True, text=True) - minisign_password = cmd.stdout - # Create directory run_command( [ @@ -86,9 +86,11 @@ def main(): pass architectures = { - "x86_64-unknown-linux-musl": "amd64", - "aarch64-unknown-linux-musl": "arm64", - "arm-unknown-linux-gnueabihf": "armhf", + "x86_64-unknown-linux-gnu": "amd64", + # I would like to build for those targets instead: + # "x86_64-unknown-linux-musl": "amd64", + # "aarch64-unknown-linux-musl": "arm64", + # "arm-unknown-linux-gnueabihf": "armhf", } all_files = [] @@ -120,32 +122,55 @@ $ sudo systemctl enable --now reaction@reaction.jsonnet.service for architecture_rs, architecture_pretty in architectures.items(): # Cargo clean - run_command(["cargo", "clean"]) + # run_command(["cargo", "clean"]) - # Install toolchain + # Build docker image + run_command(["docker", "pull", "rust:bookworm"]) + run_command(["docker", "build", "-t", "rust:reaction", "."]) + + binaries = [ + # Binaries + "reaction", + "reaction-plugin-virtual", + "reaction-plugin-ipset", + ] + + # Build run_command( [ - "rustup", - "toolchain", - "install", - f"stable-{architecture_rs}", - "--force-non-host", # I know, I know! - "--profile", - "minimal", + "docker", + "run", + "--rm", + "-u", str(os.getuid()), + "-v", ".:/reaction", + "rust:reaction", + "sh", "-c", + " && ".join([ + f"cargo build --release --target {architecture_rs} --package {binary}" + for binary in binaries + ]) ] ) - # Build - run_command(["cross", "build", "--release", "--target", architecture_rs]) - # Build .deb - cmd = run_command( - ["cargo-deb", f"--target={architecture_rs}", "--no-build", "--no-strip"] - ) + debs = [ + "reaction", + "reaction-plugin-ipset", + ] + for deb in debs: + cmd = run_command( + [ + "cargo-deb", + "--target", architecture_rs, + "--package", deb, + "--no-build", + "--no-strip" + ] + ) deb_dir = os.path.join("./target", architecture_rs, "debian") - deb_name = [f for f in os.listdir(deb_dir) if f.endswith(".deb")][0] - deb_path = os.path.join(deb_dir, deb_name) + deb_names = [f for f in os.listdir(deb_dir) if f.endswith(".deb")] + deb_paths = [os.path.join(deb_dir, deb_name) for deb_name in deb_names] # Archive files_path = os.path.join("./target", architecture_rs, "release") @@ -159,9 +184,7 @@ $ sudo systemctl enable --now reaction@reaction.jsonnet.service except FileExistsError: pass - files = [ - # Binaries - "reaction", + files = binaries + [ # Shell completion "reaction.bash", "reaction.fish", @@ -187,16 +210,17 @@ $ sudo systemctl enable --now reaction@reaction.jsonnet.service os.chdir(root_dir) - if args.publish: - # Sign - run_command( - ["minisign", "-Sm", deb_path, tar_path], - text=True, - input=minisign_password, - ) - deb_sig = f"{deb_path}.minisig" - tar_sig = f"{tar_path}.minisig" + # Sign + run_command( + ["minisign", "-Sm", tar_path] + deb_paths, + text=True, + input=minisign_password, + ) + deb_sig_paths = [f"{deb_path}.minisig" for deb_path in deb_paths] + deb_sig_names = [f"{deb_name}.minisig" for deb_name in deb_names] + tar_sig = f"{tar_path}.minisig" + if args.publish: # Push run_command( [ @@ -204,18 +228,25 @@ $ sudo systemctl enable --now reaction@reaction.jsonnet.service "-az", # "-e", "ssh -J pica01", tar_path, tar_sig, - deb_path, - deb_sig, + ] + + deb_paths + + deb_sig_paths + + [ f"akesi:/var/www/static/reaction/releases/{tag}/", ] ) + else: + # Copy + run_command(["cp", tar_path, tar_sig] + deb_paths + deb_sig_paths + [local_dir]) - all_files.extend([tar_path, tar_sig, deb_path, deb_sig]) + all_files.extend([tar_path, tar_sig]) + all_files.extend(deb_paths) + all_files.extend(deb_sig_paths) - # Instructions + # Instructions - instructions.append( - f""" + instructions.append( + f""" ## Tar installation ({architecture_pretty} linux) ```bash @@ -223,32 +254,42 @@ curl -O https://static.ppom.me/reaction/releases/{tag}/{tar_name} \\ -O https://static.ppom.me/reaction/releases/{tag}/{tar_name}.minisig \\ && minisign -VP RWSpLTPfbvllNqRrXUgZzM7mFjLUA7PQioAItz80ag8uU4A2wtoT2DzX -m {tar_name} \\ && rm {tar_name}.minisig \\ - && cd {tar_name} \\ + && tar xvf {tar_name} \\ + && cd {pkg_name} \\ && sudo make install ``` - """.strip() - ) - instructions.append( - f""" +If you want to install the ipset plugin as well: +```bash +sudo apt install -y libipset-dev && sudo make install-ipset +``` +""".strip() + ) + + instructions.append( + f""" ## Debian installation ({architecture_pretty} linux) ```bash -curl -O https://static.ppom.me/reaction/releases/{tag}/{deb_name} \\ - -O https://static.ppom.me/reaction/releases/{tag}/{deb_name}.minisig \\ - && minisign -VP RWSpLTPfbvllNqRrXUgZzM7mFjLUA7PQioAItz80ag8uU4A2wtoT2DzX -m {deb_name} \\ - && rm {deb_name}.minisig \\ - && sudo apt install ./{deb_name} +curl \\ +{"\n".join([ + f" -O https://static.ppom.me/reaction/releases/{tag}/{deb_name} \\" + for deb_name in deb_names + deb_sig_names +])} +{"\n".join([ + f" && minisign -VP RWSpLTPfbvllNqRrXUgZzM7mFjLUA7PQioAItz80ag8uU4A2wtoT2DzX -m {deb_name} \\" + for deb_name in deb_names +])} + && rm {" ".join(deb_sig_names)} \\ + && sudo apt install {" ".join([f"./{deb_name}" for deb_name in deb_names])} ``` *You can also use [this third-party package repository](https://packages.azlux.fr).* - """.strip() - ) - else: - # Copy - run_command(["cp", tar_path, deb_path, local_dir]) +""".strip() + ) if not args.publish: + print("\n\n".join(instructions)) return # Release