Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce nixos module for tclip #64

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 194 additions & 65 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,92 +12,221 @@
};
};

outputs = { self, nixpkgs, utils, gomod2nix }:
utils.lib.eachSystem [
outputs = {
self,
nixpkgs,
utils,
gomod2nix,
}:
{
overlays.default = final: prev: {
tclip = self.packages."${prev.system}".tclip;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I look at other examples https://github.com/ryantm/agenix they are structured differently; t
the overlay defines the packages and then packages attribute just pull it out of nixpkgs itself.

This goes in the other direction; not sure how "wrong" that is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any strong feelings here, as long as it works well and doesn't break or complicate anything.

tclipd = self.packages."${prev.system}".tclipd;
};

nixosModules.tclip = {
pkgs,
config,
lib,
...
}:
with lib; let
cfg = config.services.tclip;
in {
options.services.tclip = {
enable = mkEnableOption "Enable tclip service";

package = mkOption {
type = types.package;
description = ''
tclip package to use
'';
default = self.packages."${pkgs.system}".tclipd;
};

dataDir = mkOption {
type = types.path;
default = "/var/lib/tclip";
description = "Path to data dir";
};

hostname = mkOption {
type = types.str;
default = "paste";
description = "Hostname to use on your tailnet";
};

funnel = mkOption {
type = types.bool;
default = false;
description = "if set, expose individual pastes to the public internet with Funnel";
};

user = mkOption {
type = types.str;
default = "tclip";
description = "User account under which tclip runs.";
};

group = mkOption {
type = types.str;
default = "tclip";
description = "Group account under which tclip runs.";
};

tailscaleAuthKeyFile = mkOption {
type = types.path;
description = "Path to file containing the Tailscale Auth Key";
};

verbose = mkOption {
type = types.bool;
default = false;
};
};
config = mkIf cfg.enable {
environment.systemPackages = [
self.packages."${pkgs.system}".tclip
];

users.users."${cfg.user}" = {
home = cfg.dataDir;
createHome = true;
group = "${cfg.group}";
isSystemUser = true;
isNormalUser = false;
description = "User for tclip service";
};
users.groups."${cfg.group}" = {};

systemd.services.tclip = {
enable = true;
script = let
args =
[
"--data-dir"
cfg.dataDir
"--hostname"
cfg.hostname
]
++ lib.optionals cfg.verbose ["--tsnet-verbose"]
++ lib.optionals cfg.funnel ["--use-funnel"];
in ''
${lib.optionalString (cfg.tailscaleAuthKeyFile != null) ''
export TS_AUTHKEY="$(head -n1 ${lib.escapeShellArg cfg.tailscaleAuthKeyFile})"
''}
${cfg.package}/bin/tclipd ${builtins.concatStringsSep " " args};
'';
wantedBy = ["multi-user.target"];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Restart = "always";
RestartSec = "15";
WorkingDirectory = "${cfg.dataDir}";
};
};
};
};

nixosModules.default = self.nixosModules.tclip;
}
// utils.lib.eachSystem [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
] (system:
let
graft = pkgs: pkg: pkg.override {
buildGoModule = pkgs.buildGo122Module;
};
pkgs = import nixpkgs {
inherit system;
overlays = [ gomod2nix.overlays.default (final: prev: {
] (system: let
graft = pkgs: pkg:
pkg.override {
buildGoModule = pkgs.buildGo122Module;
};
pkgs = import nixpkgs {
inherit system;
overlays = [
gomod2nix.overlays.default
(final: prev: {
go = prev.go;
go-tools = graft prev prev.go-tools;
gotools = graft prev prev.gotools;
gopls = graft prev prev.gopls;
}) ];
})
];
};
version = builtins.substring 0 8 self.lastModifiedDate;
in {
# Formatter for your nix files, available through 'nix fmt'
# Other options beside 'alejandra' include 'nixpkgs-fmt'
formatter = pkgs.alejandra;

packages = rec {
tclipd = pkgs.buildGoApplication {
pname = "tclipd";
version = "0.1.0-${version}";
go = pkgs.go;
src = ./.;
subPackages = "cmd/tclipd";
modules = ./gomod2nix.toml;
};
version = builtins.substring 0 8 self.lastModifiedDate;
in {
packages = rec {
tclipd = pkgs.buildGoApplication {
pname = "tclipd";
version = "0.1.0-${version}";
go = pkgs.go;
src = ./.;
subPackages = "cmd/tclipd";
modules = ./gomod2nix.toml;
};

tclip = pkgs.buildGoApplication {
pname = "tclip";
inherit (tclipd) src version modules;
subPackages = "cmd/tclip";
go = pkgs.go;
tclip = pkgs.buildGoApplication {
pname = "tclip";
inherit (tclipd) src version modules;
subPackages = "cmd/tclip";
go = pkgs.go;

CGO_ENABLED = "0";
};
CGO_ENABLED = "0";
};

docker = pkgs.dockerTools.buildLayeredImage {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are from formatting; I added formatter as an attribute so nix fmt should keep this consistent.

name = "ghcr.io/tailscale-dev/tclip";
tag = "latest";
config.Cmd = [ "${tclipd}/bin/tclipd" ];
contents = [ pkgs.cacert ];
};
docker = pkgs.dockerTools.buildLayeredImage {
name = "ghcr.io/tailscale-dev/tclip";
tag = "latest";
config.Cmd = ["${tclipd}/bin/tclipd"];
contents = [pkgs.cacert];
};

portable-service = let
web-service = pkgs.substituteAll {
name = "tclip.service";
src = ./run/portable-service/tclip.service.in;
inherit tclipd;
};
in pkgs.portableService {
portable-service = let
web-service = pkgs.substituteAll {
name = "tclip.service";
src = ./run/portable-service/tclip.service.in;
inherit tclipd;
};
in
pkgs.portableService {
inherit (tclipd) version;
pname = "tclip";
description = "The tclip service";
homepage = "https://github.com/tailscale-dev/tclip";
units = [ web-service ];
symlinks = [{
object = "${pkgs.cacert}/etc/ssl";
symlink = "/etc/ssl";
}];
units = [web-service];
symlinks = [
{
object = "${pkgs.cacert}/etc/ssl";
symlink = "/etc/ssl";
}
];
};

default = docker;
};
default = docker;
};

apps.default =
utils.lib.mkApp { drv = self.packages.${system}.default; };
apps.default =
utils.lib.mkApp {drv = self.packages.${system}.default;};

devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
go
gopls
gotools
go-tools
gomod2nix.packages.${system}.default
sqlite-interactive
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
go
gopls
gotools
go-tools
gomod2nix.packages.${system}.default
sqlite-interactive

yarn
nodejs
];
yarn
nodejs
];

TSNET_HOSTNAME = "paste-devel";
};
}) // {};
TSNET_HOSTNAME = "paste-devel";
};
})
// {};
}
Loading