-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement flake
- Loading branch information
Showing
2 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
{ | ||
description = "Transfer.sh"; | ||
|
||
inputs.flake-utils.url = "github:numtide/flake-utils"; | ||
|
||
outputs = { self, nixpkgs, flake-utils }: | ||
let | ||
transfer-sh = pkgs: pkgs.buildGoModule { | ||
src = self; | ||
name = "transfer.sh"; | ||
vendorSha256 = "sha256-bgQUMiC33yVorcKOWhegT1/YU+fvxsz2pkeRvjf3R7g="; | ||
}; | ||
in | ||
|
||
flake-utils.lib.eachDefaultSystem ( | ||
system: | ||
let | ||
pkgs = nixpkgs.legacyPackages.${system}; | ||
in | ||
rec { | ||
packages = flake-utils.lib.flattenTree { | ||
transfer-sh = transfer-sh pkgs; | ||
}; | ||
defaultPackage = packages.transfer-sh; | ||
apps.transfer-sh = flake-utils.lib.mkApp { drv = packages.transfer-sh; }; | ||
defaultApp = apps.transfer-sh; | ||
} | ||
) // rec { | ||
|
||
nixosModules = { | ||
transfer-sh = { config, lib, pkgs, ... }: with lib; let | ||
RUNTIME_DIR = "/var/lib/transfer.sh"; | ||
cfg = config.services.transfer-sh; | ||
|
||
general_options = { | ||
|
||
enable = mkEnableOption "Transfer.sh service"; | ||
listener = mkOption { default = 80; type = types.int; description = "port to use for http (:80)"; }; | ||
profile-listener = mkOption { default = 6060; type = types.int; description = "port to use for profiler (:6060)"; }; | ||
force-https = mkOption { type = types.nullOr types.bool; description = "redirect to https"; }; | ||
tls-listener = mkOption { default = 443; type = types.int; description = "port to use for https (:443)"; }; | ||
tls-listener-only = mkOption { type = types.nullOr types.bool; description = "flag to enable tls listener only"; }; | ||
tls-cert-file = mkOption { type = types.nullOr types.str; description = "path to tls certificate"; }; | ||
tls-private-key = mkOption { type = types.nullOr types.str; description = "path to tls private key "; }; | ||
http-auth-user = mkOption { type = types.nullOr types.str; description = "user for basic http auth on upload"; }; | ||
http-auth-pass = mkOption { type = types.nullOr types.str; description = "pass for basic http auth on upload"; }; | ||
ip-whitelist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips allowed to connect to the service"; }; | ||
ip-blacklist = mkOption { type = types.nullOr types.str; description = "comma separated list of ips not allowed to connect to the service"; }; | ||
temp-path = mkOption { type = types.nullOr types.str; description = "path to temp folder"; }; | ||
web-path = mkOption { type = types.nullOr types.str; description = "path to static web files (for development or custom front end)"; }; | ||
proxy-path = mkOption { type = types.nullOr types.str; description = "path prefix when service is run behind a proxy"; }; | ||
proxy-port = mkOption { type = types.nullOr types.str; description = "port of the proxy when the service is run behind a proxy"; }; | ||
ga-key = mkOption { type = types.nullOr types.str; description = "google analytics key for the front end"; }; | ||
uservoice-key = mkOption { type = types.nullOr types.str; description = "user voice key for the front end"; }; | ||
lets-encrypt-hosts = mkOption { type = types.nullOr (types.listOf types.str); description = "hosts to use for lets encrypt certificates"; }; | ||
log = mkOption { type = types.nullOr types.str; description = "path to log file"; }; | ||
cors-domains = mkOption { type = types.nullOr (types.listOf types.str); description = "comma separated list of domains for CORS, setting it enable CORS "; }; | ||
clamav-host = mkOption { type = types.nullOr types.str; description = "host for clamav feature"; }; | ||
rate-limit = mkOption { type = types.nullOr types.int; description = "request per minute"; }; | ||
max-upload-size = mkOption { type = types.nullOr types.int; description = "max upload size in kilobytes "; }; | ||
purge-days = mkOption { type = types.nullOr types.int; description = "number of days after the uploads are purged automatically "; }; | ||
random-token-length = mkOption { type = types.nullOr types.int; description = "length of the random token for the upload path (double the size for delete path)"; }; | ||
|
||
}; | ||
|
||
provider_options = { | ||
|
||
aws = { | ||
enable = mkEnableOption "Enable AWS backend"; | ||
aws-access-key = mkOption { type = types.str; description = "aws access key"; }; | ||
aws-secret-key = mkOption { type = types.str; description = "aws secret key"; }; | ||
bucket = mkOption { type = types.str; description = "aws bucket "; }; | ||
s3-endpoint = mkOption { | ||
type = types.nullOr types.str; | ||
description = '' | ||
Custom S3 endpoint. | ||
If you specify the s3-region, you don't need to set the endpoint URL since the correct endpoint will used automatically. | ||
''; | ||
}; | ||
s3-region = mkOption { type = types.str; description = "region of the s3 bucket eu-west-"; }; | ||
s3-no-multipart = mkOption { type = types.nullOr types.bool; description = "disables s3 multipart upload "; }; | ||
s3-path-style = mkOption { type = types.nullOr types.str; description = "Forces path style URLs, required for Minio. "; }; | ||
}; | ||
|
||
storj = { | ||
enable = mkEnableOption "Enable storj backend"; | ||
storj-access = mkOption { type = types.str; description = "Access for the project"; }; | ||
storj-bucket = mkOption { type = types.str; description = "Bucket to use within the project"; }; | ||
}; | ||
|
||
gdrive = { | ||
enable = mkEnableOption "Enable gdrive backend"; | ||
gdrive-client-json = mkOption { type = types.str; description = "oauth client json config for gdrive provider"; }; | ||
gdrive-chunk-size = mkOption { default = 8; type = types.nullOr types.int; description = "chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB)"; }; | ||
basedir = mkOption { type = types.str; description = "path storage for gdrive provider"; default = "${cfg.stateDir}/store"; }; | ||
purge-interval = mkOption { type = types.nullOr types.int; description = "interval in hours to run the automatic purge for (not applicable to S3 and Storj)"; }; | ||
|
||
}; | ||
|
||
local = { | ||
enable = mkEnableOption "Enable gdrive backend"; | ||
basedir = mkOption { type = types.str; description = "path storage for local provider"; default = "${cfg.stateDir}/store"; }; | ||
purge-interval = mkOption { type = types.nullOr types.int; description = "interval in hours to run the automatic purge for (not applicable to S3 and Storj)"; }; | ||
}; | ||
|
||
}; | ||
in | ||
{ | ||
options.services.transfer-sh = fold recursiveUpdate {} [ | ||
general_options | ||
{ | ||
provider = provider_options; | ||
user = mkOption { | ||
type = types.str; | ||
description = "User to run the service under"; | ||
default = "transfer.sh"; | ||
}; | ||
group = mkOption { | ||
type = types.str; | ||
description = "Group to run the service under"; | ||
default = "transfer.sh"; | ||
}; | ||
stateDir = mkOption { | ||
type = types.path; | ||
description = "Variable state directory"; | ||
default = RUNTIME_DIR; | ||
}; | ||
} | ||
]; | ||
|
||
config = let | ||
|
||
mkFlags = cfg: options: | ||
let | ||
mkBoolFlag = option: if cfg.${option} then [ "--${option}" ] else []; | ||
mkFlag = option: | ||
if isBool cfg.${option} | ||
then mkBoolFlag option | ||
else [ "--${option}" "${cfg.${option}}" ]; | ||
|
||
in | ||
lists.flatten (map (mkFlag) (filter (option: cfg.${option} != null && option != "enable") options)); | ||
|
||
aws-config = (mkFlags cfg.provider.aws (attrNames provider_options)) ++ [ "--provider" "aws" ]; | ||
gdrive-config = mkFlags cfg.provider.gdrive (attrNames provider_options.gdrive) ++ [ "--provider" "gdrive" ]; | ||
storj-config = mkFlags cfg.provider.storj (attrNames provider_options.storj) ++ [ "--provider" "storj" ]; | ||
local-config = mkFlags cfg.provider.local (attrNames provider_options.local) ++ [ "--provider" "local" ]; | ||
|
||
general-config = concatStringsSep " " (mkFlags cfg (attrNames general_options)); | ||
provider-config = concatStringsSep " " ( | ||
if cfg.provider.aws.enable && !cfg.provider.storj.enable && !cfg.provider.gdrive.enable && !cfg.provider.local.enable then aws-config | ||
else if !cfg.provider.aws.enable && cfg.provider.storj.enable && !cfg.provider.gdrive.enable && !cfg.provider.local.enable then storj-config | ||
else if !cfg.provider.aws.enable && !cfg.provider.storj.enable && cfg.provider.gdrive.enable && !cfg.provider.local.enable then gdrive-config | ||
else if !cfg.provider.aws.enable && !cfg.provider.storj.enable && !cfg.provider.gdrive.enable && cfg.provider.local.enable then local-config | ||
else throw "transfer.sh requires exactly one provider (aws, storj, gdrive, local)" | ||
); | ||
|
||
in | ||
lib.mkIf cfg.enable | ||
{ | ||
systemd.tmpfiles.rules = [ | ||
"d ${cfg.stateDir} 0750 ${cfg.user} ${cfg.group} - -" | ||
] ++ optional cfg.provider.gdrive.enable cfg.provider.gdrive.basedir | ||
++ optional cfg.provider.local.enable cfg.provider.local.basedir; | ||
|
||
systemd.services.transfer-sh = { | ||
wantedBy = [ "multi-user.target" ]; | ||
after = [ "network.target" ]; | ||
serviceConfig = { | ||
User = cfg.user; | ||
Group = cfg.group; | ||
ExecStart = "${transfer-sh pkgs}/bin/transfer.sh ${general-config} ${provider-config} "; | ||
}; | ||
}; | ||
|
||
networking.firewall.allowedTCPPorts = [ cfg.listener cfg.profile-listener cfg.tls-listener ]; | ||
}; | ||
}; | ||
|
||
default = { self, pkgs, ... }: { | ||
imports = [ nixosModules.transfer-sh ]; | ||
# Network configuration. | ||
|
||
# useDHCP is generally considered to better be turned off in favor | ||
# of <adapter>.useDHCP | ||
networking.useDHCP = false; | ||
networking.firewall.allowedTCPPorts = []; | ||
|
||
# Enable the inventaire server. | ||
services.transfer-sh = { | ||
enable = true; | ||
provider.local = { | ||
enable = true; | ||
}; | ||
}; | ||
|
||
nixpkgs.config.allowUnfree = true; | ||
}; | ||
}; | ||
|
||
|
||
nixosConfigurations."container" = nixpkgs.lib.nixosSystem { | ||
system = "x86_64-linux"; | ||
modules = [ | ||
nixosModules.default | ||
({ ... }: { boot.isContainer = true; }) | ||
]; | ||
}; | ||
|
||
}; | ||
} |