Merge master into staging-next
This commit is contained in:
commit
95c5daaba5
@ -198,6 +198,13 @@
|
||||
<link xlink:href="options.html#opt-services.kanata.enable">services.kanata</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://www.getoutline.com/">Outline</link>,
|
||||
a wiki and knowledge base similar to Notion. Available as
|
||||
<link linkend="opt-services.outline.enable">services.outline</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://github.com/aiberia/persistent-evdev">persistent-evdev</link>,
|
||||
|
@ -74,6 +74,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||
- [kanata](https://github.com/jtroo/kanata), a tool to improve keyboard comfort and usability with advanced customization.
|
||||
Available as [services.kanata](options.html#opt-services.kanata.enable).
|
||||
|
||||
- [Outline](https://www.getoutline.com/), a wiki and knowledge base similar to Notion. Available as [services.outline](#opt-services.outline.enable).
|
||||
|
||||
- [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable).
|
||||
|
||||
- [schleuder](https://schleuder.org/), a mailing list manager with PGP support. Enable using [services.schleuder](#opt-services.schleuder.enable).
|
||||
|
@ -1104,6 +1104,7 @@
|
||||
./services/web-apps/prosody-filer.nix
|
||||
./services/web-apps/matomo.nix
|
||||
./services/web-apps/openwebrx.nix
|
||||
./services/web-apps/outline.nix
|
||||
./services/web-apps/restya-board.nix
|
||||
./services/web-apps/sogo.nix
|
||||
./services/web-apps/rss-bridge.nix
|
||||
|
777
nixos/modules/services/web-apps/outline.nix
Normal file
777
nixos/modules/services/web-apps/outline.nix
Normal file
@ -0,0 +1,777 @@
|
||||
{ config, lib, pkgs, ...}:
|
||||
|
||||
let
|
||||
defaultUser = "outline";
|
||||
cfg = config.services.outline;
|
||||
in
|
||||
{
|
||||
# See here for a reference of all the options:
|
||||
# https://github.com/outline/outline/blob/v0.65.2/.env.sample
|
||||
# https://github.com/outline/outline/blob/v0.65.2/app.json
|
||||
# https://github.com/outline/outline/blob/v0.65.2/server/env.ts
|
||||
# https://github.com/outline/outline/blob/v0.65.2/shared/types.ts
|
||||
# The order is kept the same here to make updating easier.
|
||||
options.services.outline = {
|
||||
enable = lib.mkEnableOption "outline";
|
||||
|
||||
package = lib.mkOption {
|
||||
default = pkgs.outline;
|
||||
defaultText = lib.literalExpression "pkgs.outline";
|
||||
type = lib.types.package;
|
||||
example = lib.literalExpression ''
|
||||
pkgs.outline.overrideAttrs (super: {
|
||||
# Ignore the domain part in emails that come from OIDC. This is might
|
||||
# be helpful if you want multiple users with different email providers
|
||||
# to still land in the same team. Note that this effectively makes
|
||||
# Outline a single-team instance.
|
||||
patchPhase = ${"''"}
|
||||
sed -i 's/const domain = parts\.length && parts\[1\];/const domain = "example.com";/g' server/routes/auth/providers/oidc.ts
|
||||
${"''"};
|
||||
})
|
||||
'';
|
||||
description = "Outline package to use.";
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = ''
|
||||
User under which the service should run. If this is the default value,
|
||||
the user will be created, with the specified group as the primary
|
||||
group.
|
||||
'';
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = ''
|
||||
Group under which the service should run. If this is the default value,
|
||||
the group will be created.
|
||||
'';
|
||||
};
|
||||
|
||||
sequelizeArguments = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
example = "--env=production-ssl-disabled";
|
||||
description = ''
|
||||
Optional arguments to pass to <literal>sequelize</literal> calls.
|
||||
'';
|
||||
};
|
||||
|
||||
#
|
||||
# Required options
|
||||
#
|
||||
|
||||
secretKeyFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/outline/secret_key";
|
||||
description = ''
|
||||
File path that contains the application secret key. It must be 32
|
||||
bytes long and hex-encoded. If the file does not exist, a new key will
|
||||
be generated and saved here.
|
||||
'';
|
||||
};
|
||||
|
||||
utilsSecretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/outline/utils_secret";
|
||||
description = ''
|
||||
File path that contains the utility secret key. If the file does not
|
||||
exist, a new key will be generated and saved here.
|
||||
'';
|
||||
};
|
||||
|
||||
databaseUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "local";
|
||||
description = ''
|
||||
URI to use for the main PostgreSQL database. If this needs to include
|
||||
credentials that shouldn't be world-readable in the Nix store, set an
|
||||
environment file on the systemd service and override the
|
||||
<literal>DATABASE_URL</literal> entry. Pass the string
|
||||
<literal>local</literal> to setup a database on the local server.
|
||||
'';
|
||||
};
|
||||
|
||||
redisUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "local";
|
||||
description = ''
|
||||
Connection to a redis server. If this needs to include credentials
|
||||
that shouldn't be world-readable in the Nix store, set an environment
|
||||
file on the systemd service and override the
|
||||
<literal>REDIS_URL</literal> entry. Pass the string
|
||||
<literal>local</literal> to setup a local Redis database.
|
||||
'';
|
||||
};
|
||||
|
||||
publicUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "http://localhost:3000";
|
||||
description = "The fully qualified, publicly accessible URL";
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 3000;
|
||||
description = "Listening port.";
|
||||
};
|
||||
|
||||
storage = lib.mkOption {
|
||||
description = ''
|
||||
To support uploading of images for avatars and document attachments an
|
||||
s3-compatible storage must be provided. AWS S3 is recommended for
|
||||
redundency however if you want to keep all file storage local an
|
||||
alternative such as <link xlink:href="https://github.com/minio/minio">minio</link>
|
||||
can be used.
|
||||
|
||||
A more detailed guide on setting up S3 is available
|
||||
<link xlink:href="https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f">here</link>.
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
accessKey = "...";
|
||||
secretKeyFile = "/somewhere";
|
||||
uploadBucketUrl = "https://minio.example.com";
|
||||
uploadBucketName = "outline";
|
||||
region = "us-east-1";
|
||||
}
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
accessKey = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "S3 access key.";
|
||||
};
|
||||
secretKeyFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "File path that contains the S3 secret key.";
|
||||
};
|
||||
region = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "xx-xxxx-x";
|
||||
description = "AWS S3 region name.";
|
||||
};
|
||||
uploadBucketUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
URL endpoint of an S3-compatible API where uploads should be
|
||||
stored.
|
||||
'';
|
||||
};
|
||||
uploadBucketName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Name of the bucket where uploads should be stored.";
|
||||
};
|
||||
uploadMaxSize = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 26214400;
|
||||
description = "Maxmium file size for uploads.";
|
||||
};
|
||||
forcePathStyle = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Force S3 path style.";
|
||||
};
|
||||
acl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "private";
|
||||
description = "ACL setting.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#
|
||||
# Authentication
|
||||
#
|
||||
|
||||
slackAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure Slack auth, you'll need to create an Application at
|
||||
https://api.slack.com/apps
|
||||
|
||||
When configuring the Client ID, add a redirect URL under "OAuth & Permissions"
|
||||
to <literal>https://[publicUrl]/auth/slack.callback</literal>.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
clientId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication key.";
|
||||
};
|
||||
secretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the authentication secret.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
googleAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure Google auth, you'll need to create an OAuth Client ID at
|
||||
https://console.cloud.google.com/apis/credentials
|
||||
|
||||
When configuring the Client ID, add an Authorized redirect URI to
|
||||
<literal>https://[publicUrl]/auth/google.callback</literal>.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
clientId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication client identifier.";
|
||||
};
|
||||
clientSecretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the authentication secret.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
azureAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure Microsoft/Azure auth, you'll need to create an OAuth
|
||||
Client. See
|
||||
<link xlink:href="https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4">the guide</link>
|
||||
for details on setting up your Azure App.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
clientId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication client identifier.";
|
||||
};
|
||||
clientSecretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the authentication secret.";
|
||||
};
|
||||
resourceAppId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication application resource ID.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
oidcAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure generic OIDC auth, you'll need some kind of identity
|
||||
provider. See the documentation for whichever IdP you use to fill out
|
||||
all the fields. The redirect URL is
|
||||
<literal>https://[publicUrl]/auth/oidc.callback</literal>.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
clientId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication client identifier.";
|
||||
};
|
||||
clientSecretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the authentication secret.";
|
||||
};
|
||||
authUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "OIDC authentication URL endpoint.";
|
||||
};
|
||||
tokenUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "OIDC token URL endpoint.";
|
||||
};
|
||||
userinfoUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "OIDC userinfo URL endpoint.";
|
||||
};
|
||||
usernameClaim = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Specify which claims to derive user information from. Supports any
|
||||
valid JSON path with the JWT payload
|
||||
'';
|
||||
default = "preferred_username";
|
||||
};
|
||||
displayName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Display name for OIDC authentication.";
|
||||
default = "OpenID";
|
||||
};
|
||||
scopes = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "OpenID authentication scopes.";
|
||||
default = [ "openid" "profile" "email" ];
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
#
|
||||
# Optional configuration
|
||||
#
|
||||
|
||||
sslKeyFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
File path that contains the Base64-encoded private key for HTTPS
|
||||
termination. This is only required if you do not use an external reverse
|
||||
proxy. See
|
||||
<link xlink:href="https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4">the documentation</link>.
|
||||
'';
|
||||
};
|
||||
sslCertFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
File path that contains the Base64-encoded certificate for HTTPS
|
||||
termination. This is only required if you do not use an external reverse
|
||||
proxy. See
|
||||
<link xlink:href="https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4">the documentation</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
cdnUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
If using a Cloudfront/Cloudflare distribution or similar it can be set
|
||||
using this option. This will cause paths to JavaScript files,
|
||||
stylesheets and images to be updated to the hostname defined here. In
|
||||
your CDN configuration the origin server should be set to public URL.
|
||||
'';
|
||||
};
|
||||
|
||||
forceHttps = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Auto-redirect to HTTPS in production. The default is
|
||||
<literal>true</literal> but you may set this to <literal>false</literal>
|
||||
if you can be sure that SSL is terminated at an external loadbalancer.
|
||||
'';
|
||||
};
|
||||
|
||||
enableUpdateCheck = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Have the installation check for updates by sending anonymized statistics
|
||||
to the maintainers.
|
||||
'';
|
||||
};
|
||||
|
||||
concurrency = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 1;
|
||||
description = ''
|
||||
How many processes should be spawned. For a rough estimate, divide your
|
||||
server's available memory by 512.
|
||||
'';
|
||||
};
|
||||
|
||||
maximumImportSize = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5120000;
|
||||
description = ''
|
||||
The maximum size of document imports. Overriding this could be required
|
||||
if you have especially large Word documents with embedded imagery.
|
||||
'';
|
||||
};
|
||||
|
||||
debugOutput = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.enum [ "http" ]);
|
||||
default = null;
|
||||
description = "Set this to <literal>http</literal> log HTTP requests.";
|
||||
};
|
||||
|
||||
slackIntegration = lib.mkOption {
|
||||
description = ''
|
||||
For a complete Slack integration with search and posting to channels
|
||||
this configuration is also needed. See here for details:
|
||||
https://wiki.generaloutline.com/share/be25efd1-b3ef-4450-b8e5-c4a4fc11e02a
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
verificationTokenFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the verification token.";
|
||||
};
|
||||
appId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Application ID.";
|
||||
};
|
||||
messageActions = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable message actions.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
googleAnalyticsId = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Optionally enable Google Analytics to track page views in the knowledge
|
||||
base.
|
||||
'';
|
||||
};
|
||||
|
||||
sentryDsn = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Optionally enable <link xlink:href="https://sentry.io/">Sentry</link> to
|
||||
track errors and performance.
|
||||
'';
|
||||
};
|
||||
|
||||
logo = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Custom logo displayed on the authentication screen. This will be scaled
|
||||
to a height of 60px.
|
||||
'';
|
||||
};
|
||||
|
||||
smtp = lib.mkOption {
|
||||
description = ''
|
||||
To support sending outgoing transactional emails such as
|
||||
"document updated" or "you've been invited" you'll need to provide
|
||||
authentication for an SMTP server.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (lib.types.submodule {
|
||||
options = {
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Host name or IP adress of the SMTP server.";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "TCP port of the SMTP server.";
|
||||
};
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Username to authenticate with.";
|
||||
};
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
File path containing the password to authenticate with.
|
||||
'';
|
||||
};
|
||||
fromEmail = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Sender email in outgoing mail.";
|
||||
};
|
||||
replyEmail = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Reply address in outgoing mail.";
|
||||
};
|
||||
tlsCiphers = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Override SMTP cipher configuration.";
|
||||
};
|
||||
secure = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Use a secure SMTP connection.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
defaultLanguage = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"da_DK"
|
||||
"de_DE"
|
||||
"en_US"
|
||||
"es_ES"
|
||||
"fa_IR"
|
||||
"fr_FR"
|
||||
"it_IT"
|
||||
"ja_JP"
|
||||
"ko_KR"
|
||||
"nl_NL"
|
||||
"pl_PL"
|
||||
"pt_BR"
|
||||
"pt_PT"
|
||||
"ru_RU"
|
||||
"sv_SE"
|
||||
"th_TH"
|
||||
"vi_VN"
|
||||
"zh_CN"
|
||||
"zh_TW"
|
||||
];
|
||||
default = "en_US";
|
||||
description = ''
|
||||
The default interface language. See
|
||||
<link xlink:href="https://translate.getoutline.com/">translate.getoutline.com</link>
|
||||
for a list of available language codes and their rough percentage
|
||||
translated.
|
||||
'';
|
||||
};
|
||||
|
||||
rateLimiter.enable = lib.mkEnableOption "rate limiter for the application web server";
|
||||
rateLimiter.requests = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5000;
|
||||
description = "Maximum number of requests in a throttling window.";
|
||||
};
|
||||
rateLimiter.durationWindow = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 60;
|
||||
description = "Length of a throttling window.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
|
||||
${defaultUser} = {
|
||||
isSystemUser = true;
|
||||
group = cfg.group;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
|
||||
${defaultUser} = { };
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"f ${cfg.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||
"f ${cfg.utilsSecretFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||
"f ${cfg.storage.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
|
||||
];
|
||||
|
||||
services.postgresql = lib.mkIf (cfg.databaseUrl == "local") {
|
||||
enable = true;
|
||||
ensureUsers = [{
|
||||
name = "outline";
|
||||
ensurePermissions."DATABASE outline" = "ALL PRIVILEGES";
|
||||
}];
|
||||
ensureDatabases = [ "outline" ];
|
||||
};
|
||||
|
||||
services.redis.servers.outline = lib.mkIf (cfg.redisUrl == "local") {
|
||||
enable = true;
|
||||
user = config.services.outline.user;
|
||||
port = 0; # Disable the TCP listener
|
||||
};
|
||||
|
||||
systemd.services.outline = let
|
||||
localRedisUrl = "redis+unix:///run/redis-outline/redis.sock";
|
||||
localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql";
|
||||
|
||||
# Create an outline-sequalize wrapper (a wrapper around the wrapper) that
|
||||
# has the config file's path baked in. This is necessary because there is
|
||||
# at least one occurrence of outline calling this from its own code.
|
||||
sequelize = pkgs.writeShellScriptBin "outline-sequelize" ''
|
||||
exec ${cfg.package}/bin/outline-sequelize \
|
||||
--config $RUNTIME_DIRECTORY/database.json \
|
||||
${cfg.sequelizeArguments} \
|
||||
"$@"
|
||||
'';
|
||||
in {
|
||||
description = "Outline wiki and knowledge base";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ]
|
||||
++ lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
||||
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
||||
requires = lib.optional (cfg.databaseUrl == "local") "postgresql.service"
|
||||
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
|
||||
path = [
|
||||
pkgs.openssl # Required by the preStart script
|
||||
sequelize
|
||||
];
|
||||
|
||||
|
||||
environment = lib.mkMerge [
|
||||
{
|
||||
NODE_ENV = "production";
|
||||
|
||||
REDIS_URL = if cfg.redisUrl == "local" then localRedisUrl else cfg.redisUrl;
|
||||
URL = cfg.publicUrl;
|
||||
PORT = builtins.toString cfg.port;
|
||||
|
||||
AWS_ACCESS_KEY_ID = cfg.storage.accessKey;
|
||||
AWS_REGION = cfg.storage.region;
|
||||
AWS_S3_UPLOAD_BUCKET_URL = cfg.storage.uploadBucketUrl;
|
||||
AWS_S3_UPLOAD_BUCKET_NAME = cfg.storage.uploadBucketName;
|
||||
AWS_S3_UPLOAD_MAX_SIZE = builtins.toString cfg.storage.uploadMaxSize;
|
||||
AWS_S3_FORCE_PATH_STYLE = builtins.toString cfg.storage.forcePathStyle;
|
||||
AWS_S3_ACL = cfg.storage.acl;
|
||||
|
||||
CDN_URL = cfg.cdnUrl;
|
||||
FORCE_HTTPS = builtins.toString cfg.forceHttps;
|
||||
ENABLE_UPDATES = builtins.toString cfg.enableUpdateCheck;
|
||||
WEB_CONCURRENCY = builtins.toString cfg.concurrency;
|
||||
MAXIMUM_IMPORT_SIZE = builtins.toString cfg.maximumImportSize;
|
||||
DEBUG = cfg.debugOutput;
|
||||
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
|
||||
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
|
||||
TEAM_LOGO = lib.optionalString (cfg.logo != null) cfg.logo;
|
||||
DEFAULT_LANGUAGE = cfg.defaultLanguage;
|
||||
|
||||
RATE_LIMITER_ENABLED = builtins.toString cfg.rateLimiter.enable;
|
||||
RATE_LIMITER_REQUESTS = builtins.toString cfg.rateLimiter.requests;
|
||||
RATE_LIMITER_DURATION_WINDOW = builtins.toString cfg.rateLimiter.durationWindow;
|
||||
}
|
||||
|
||||
(lib.mkIf (cfg.slackAuthentication != null) {
|
||||
SLACK_CLIENT_ID = cfg.slackAuthentication.clientId;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.googleAuthentication != null) {
|
||||
GOOGLE_CLIENT_ID = cfg.googleAuthentication.clientId;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.azureAuthentication != null) {
|
||||
AZURE_CLIENT_ID = cfg.azureAuthentication.clientId;
|
||||
AZURE_RESOURCE_APP_ID = cfg.azureAuthentication.resourceAppId;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.oidcAuthentication != null) {
|
||||
OIDC_CLIENT_ID = cfg.oidcAuthentication.clientId;
|
||||
OIDC_AUTH_URI = cfg.oidcAuthentication.authUrl;
|
||||
OIDC_TOKEN_URI = cfg.oidcAuthentication.tokenUrl;
|
||||
OIDC_USERINFO_URI = cfg.oidcAuthentication.userinfoUrl;
|
||||
OIDC_USERNAME_CLAIM = cfg.oidcAuthentication.usernameClaim;
|
||||
OIDC_DISPLAY_NAME = cfg.oidcAuthentication.displayName;
|
||||
OIDC_SCOPES = lib.concatStringsSep " " cfg.oidcAuthentication.scopes;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.slackIntegration != null) {
|
||||
SLACK_APP_ID = cfg.slackIntegration.appId;
|
||||
SLACK_MESSAGE_ACTIONS = builtins.toString cfg.slackIntegration.messageActions;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.smtp != null) {
|
||||
SMTP_HOST = cfg.smtp.host;
|
||||
SMTP_PORT = builtins.toString cfg.smtp.port;
|
||||
SMTP_USERNAME = cfg.smtp.username;
|
||||
SMTP_FROM_EMAIL = cfg.smtp.fromEmail;
|
||||
SMTP_REPLY_EMAIL = cfg.smtp.replyEmail;
|
||||
SMTP_TLS_CIPHERS = cfg.smtp.tlsCiphers;
|
||||
SMTP_SECURE = builtins.toString cfg.smtp.secure;
|
||||
})
|
||||
];
|
||||
|
||||
preStart = ''
|
||||
if [ ! -s ${lib.escapeShellArg cfg.secretKeyFile} ]; then
|
||||
openssl rand -hex 32 > ${lib.escapeShellArg cfg.secretKeyFile}
|
||||
fi
|
||||
if [ ! -s ${lib.escapeShellArg cfg.utilsSecretFile} ]; then
|
||||
openssl rand -hex 32 > ${lib.escapeShellArg cfg.utilsSecretFile}
|
||||
fi
|
||||
|
||||
# The config file is required for the CLI, the DATABASE_URL environment
|
||||
# variable is read by the app.
|
||||
${if (cfg.databaseUrl == "local") then ''
|
||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||
{
|
||||
"production": {
|
||||
"dialect": "postgres",
|
||||
"host": "/run/postgresql",
|
||||
"username": null,
|
||||
"password": null
|
||||
}
|
||||
}
|
||||
EOF
|
||||
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
|
||||
export PGSSLMODE=disable
|
||||
'' else ''
|
||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||
{
|
||||
"production": {
|
||||
"use_env_variable": "DATABASE_URL",
|
||||
"dialect": "postgres",
|
||||
"dialectOptions": {
|
||||
"ssl": {
|
||||
"rejectUnauthorized": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"production-ssl-disabled": {
|
||||
"use_env_variable": "DATABASE_URL",
|
||||
"dialect": "postgres"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
|
||||
''}
|
||||
|
||||
cd $RUNTIME_DIRECTORY
|
||||
${sequelize}/bin/outline-sequelize db:migrate
|
||||
'';
|
||||
|
||||
script = ''
|
||||
export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})"
|
||||
export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})"
|
||||
export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})"
|
||||
${lib.optionalString (cfg.slackAuthentication != null) ''
|
||||
export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.googleAuthentication != null) ''
|
||||
export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.azureAuthentication != null) ''
|
||||
export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.oidcAuthentication != null) ''
|
||||
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.sslKeyFile != null) ''
|
||||
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.sslCertFile != null) ''
|
||||
export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.slackIntegration != null) ''
|
||||
export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.smtp != null) ''
|
||||
export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})"
|
||||
''}
|
||||
|
||||
${if (cfg.databaseUrl == "local") then ''
|
||||
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
|
||||
export PGSSLMODE=disable
|
||||
'' else ''
|
||||
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
|
||||
''}
|
||||
|
||||
${cfg.package}/bin/outline-server
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Restart = "always";
|
||||
ProtectSystem = "strict";
|
||||
PrivateHome = true;
|
||||
PrivateTmp = true;
|
||||
UMask = "0007";
|
||||
|
||||
StateDirectory = "outline";
|
||||
StateDirectoryMode = "0750";
|
||||
RuntimeDirectory = "outline";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
# This working directory is required to find stuff like the set of
|
||||
# onboarding files:
|
||||
WorkingDirectory = "${cfg.package}/share/outline/build";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -20,13 +20,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "moonlight-qt";
|
||||
version = "4.0.0";
|
||||
version = "4.1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "moonlight-stream";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-CfOphr8QILCZg+UrImp5JO/1DTqoan5EwiQeTKR15Fo=";
|
||||
sha256 = "sha256-/HRmyf4sW8rsNmKMrlgPvq1L8gAEa6VRCyG2w5TfGkI=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -2,16 +2,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "juju";
|
||||
version = "2.9.31";
|
||||
version = "2.9.33";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "juju";
|
||||
repo = "juju";
|
||||
rev = "juju-${version}";
|
||||
sha256 = "sha256-vRe7H7wtZUTsAJa6QVP+BTDDkJsfgIlBVpGcvtU1e0g=";
|
||||
sha256 = "sha256-BK5fTPV4glBg4a4QI5L3ZBmWYGrfLDx6hAOzlNbMxJU=";
|
||||
};
|
||||
|
||||
vendorSha256 = "sha256-Tx5RazLrNZ5GMRu4/jKhuNN7m1mQw4V7TBcIed/Gssg=";
|
||||
vendorSha256 = "sha256-xBlGqHmAX08LlHmZ9Vr+j06Cf2soIPDFJKZh36ku8cw=";
|
||||
|
||||
# Disable tests because it attempts to use a mongodb instance
|
||||
doCheck = false;
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "kitsas";
|
||||
version = "3.1.1";
|
||||
version = "3.2.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "artoh";
|
||||
repo = "kitupiikki";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-nmlGLrVsTQawYHNgaax9EiutL4xgFdOD34Q4/rnB/D0=";
|
||||
sha256 = "sha256-1gp6CMoDTAp6ORnuk5wos67zygmE9s2pXwvwcR+Hwgg=";
|
||||
};
|
||||
|
||||
# QList::swapItemsAt was introduced in Qt 5.13
|
||||
|
@ -2,16 +2,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "flex-ncat";
|
||||
version = "0.1-20211223.0";
|
||||
version = "0.1-20220505.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kc2g-flex-tools";
|
||||
repo = "nCAT";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-l5IH6EtWqxMLqUfIYpaKgZE9Jq8q4+WgZIazQ2scyxg=";
|
||||
hash = "sha256-Jqoqy+W5sKfg7U/F2OpK1jAVM8rm1Tbr4RHG/mMVE0g=";
|
||||
};
|
||||
|
||||
vendorSha256 = "sha256-OzYlpC8DZQc3qo7mnl5jHlxaCNxMW+Z3VG535e+G/1o=";
|
||||
vendorSha256 = "sha256-mWZRaPbmSPBUhTCWSkU33zOOq79ylEbnjPG3gLkWeQY=";
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/kc2g-flex-tools/nCAT";
|
||||
|
@ -10,20 +10,20 @@
|
||||
, libconfig
|
||||
, pcsclite
|
||||
, uhd
|
||||
, soapysdr
|
||||
, soapysdr-with-plugins
|
||||
, libbladeRF
|
||||
, zeromq
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "srsran";
|
||||
version = "21.10";
|
||||
version = "22.04.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "srsran";
|
||||
repo = "srsran";
|
||||
rev = "release_${builtins.replaceStrings ["."] ["_"] version}";
|
||||
sha256 = "sha256-uJv8khevp7g2p4zT6bkrut67kvMu+fuL1VHDDit0viw=";
|
||||
sha256 = "sha256-jqaGlMhy6L6lRknl6Ezi0n+vNjMb7C+FN9a+QeOy/RY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake pkg-config ];
|
||||
@ -36,7 +36,7 @@ stdenv.mkDerivation rec {
|
||||
lksctp-tools
|
||||
pcsclite
|
||||
uhd
|
||||
soapysdr
|
||||
soapysdr-with-plugins
|
||||
libbladeRF
|
||||
zeromq
|
||||
];
|
||||
|
@ -27,13 +27,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "p4c";
|
||||
version = "1.2.2.1";
|
||||
version = "1.2.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "p4lang";
|
||||
repo = "p4c";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-XIZ7Cm5zfr5XA+s0aSG1WwWHCPjAYv/YoBWTRaXi9rQ=";
|
||||
sha256 = "sha256-LwRfLvnn1JAvSXPTkVcIB4PbPrrVweIv72Xk5g015ck=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "leatherman";
|
||||
version = "1.12.7";
|
||||
version = "1.12.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
sha256 = "sha256-a79/seKO6Efn6g4RWdqsP83pL5AIBAp1InjnMdOs3Qk=";
|
||||
sha256 = "sha256-5xcwktlwgP9Ltild4BliaGJBqlheDLSTKQLZjzK+nGk=";
|
||||
rev = version;
|
||||
repo = "leatherman";
|
||||
owner = "puppetlabs";
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "qpdf";
|
||||
version = "10.6.2";
|
||||
version = "10.6.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "qpdf";
|
||||
repo = "qpdf";
|
||||
rev = "release-qpdf-${version}";
|
||||
hash = "sha256-+8bH7fKJ5uZRxKX/4nMkoZGFTxm2uJEXkb1wq5FrLWs=";
|
||||
hash = "sha256-SiZA8T7N1SWlbCFosSqFosLDV/3Q7+ywvgq1iB4umdg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ perl ];
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "dunamai";
|
||||
version = "1.12.0";
|
||||
version = "1.13.0";
|
||||
format = "pyproject";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
@ -19,7 +19,7 @@ buildPythonPackage rec {
|
||||
owner = "mtkennerly";
|
||||
repo = "dunamai";
|
||||
rev = "refs/tags/v${version}";
|
||||
sha256 = "sha256-SyHml8TIcqU7KQE4IuTZbp+Jktao7ReJHQyHV8wKeWg=";
|
||||
sha256 = "sha256-0x1bwu5X1P8f51NeupEQc0eghaqQIp3jb2uwZ0JDbgQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
54
pkgs/development/python-modules/flask-basicauth/default.nix
Normal file
54
pkgs/development/python-modules/flask-basicauth/default.nix
Normal file
@ -0,0 +1,54 @@
|
||||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, fetchpatch
|
||||
, flask
|
||||
, python
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "flask-basicauth";
|
||||
version = "0.2.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jpvanhal";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-han0OjMI1XmuWKHGVpk+xZB+/+cpV1I+659zOG3hcPY=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
# The unit tests fail due to an invalid import:
|
||||
# from flask.ext.basicauth import BasicAuth
|
||||
#
|
||||
# This patch replaces it with the correct import:
|
||||
# from flask_basicauth import BasicAuth
|
||||
#
|
||||
# The patch uses the changes from this pull request,
|
||||
# and therefore can be removed once this pull request
|
||||
# has been merged:
|
||||
# https://github.com/jpvanhal/flask-basicauth/pull/29
|
||||
name = "fix-test-flask-ext-imports.patch";
|
||||
url = "https://github.com/jpvanhal/flask-basicauth/commit/23f57dc1c3d85ea6fc7f468e8d8c6f19348a0a81.patch";
|
||||
sha256 = "sha256-njUYjO0TRe3vr5D0XjIfCNcsFlShbGxtFV/DJerAKDE=";
|
||||
})
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [ flask ];
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
${python.interpreter} -m unittest discover
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "flask_basicauth" ];
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/jpvanhal/flask-basicauth";
|
||||
description = "HTTP basic access authentication for Flask";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ wesnel ];
|
||||
};
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{ buildPythonPackage
|
||||
, drawio-headless
|
||||
, fetchPypi
|
||||
, isPy3k
|
||||
, lib
|
||||
, mkdocs
|
||||
, beautifulsoup4
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "mkdocs-swagger-ui-tag";
|
||||
version = "0.4.0";
|
||||
|
||||
disabled = !isPy3k;
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-4fPn+WDHMAo3cywrMs/EoSFoBEnMYdofAeAkgwOIAb4=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ mkdocs beautifulsoup4 ];
|
||||
|
||||
pythonImportsCheck = [ "mkdocs_swagger_ui_tag" ];
|
||||
|
||||
meta = with lib; {
|
||||
description = "A MkDocs plugin supports for add Swagger UI in page.";
|
||||
homepage = "https://github.com/Blueswen/mkdocs-swagger-ui-tag";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ snpschaaf ];
|
||||
};
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "lcov";
|
||||
version = "1.15";
|
||||
version = "1.16";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "linux-test-project";
|
||||
repo = "lcov";
|
||||
rev = "v${version}";
|
||||
sha256 = "1kvc7fkp45w48f0bxwbxvxkicnjrrydki0hllg294n1wrp80zzyk";
|
||||
sha256 = "sha256-X1T5OqR6NgTNGedH1on3+XZ7369007By6tRJK8xtmbk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "json2hcl";
|
||||
version = "0.0.7";
|
||||
version = "0.1.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kvz";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-H3jDZL/guVwJIZs7PD/rIvH3ZRYQzNTU/iUvy8aXs0o=";
|
||||
sha256 = "sha256-0ku8sON4fzWAirqY+dhYAks2LSyC7OH/LKI0kb+QhpM=";
|
||||
};
|
||||
|
||||
vendorSha256 = "sha256-GxYuFak+5CJyHgC1/RsS0ub84bgmgL+bI4YKFTb+vIY=";
|
||||
|
@ -2,16 +2,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "mani";
|
||||
version = "0.12.2";
|
||||
version = "0.21.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "alajmo";
|
||||
repo = "mani";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-sjudHGqSCgwafyT8alrGvTdC3yM2zmbRcYshxSm23Ko=";
|
||||
sha256 = "sha256-eH6V7J0KHGyR//kVr0dOdBYuoR3FDbW/pSh0RhHd4A8=";
|
||||
};
|
||||
|
||||
vendorSha256 = "sha256-NnXQAf8m2cGLvwSOzQWXffiG1zyVqDPQnGAeqe7EUHY=";
|
||||
vendorSha256 = "sha256-g336is8Jjbbzmtsu3suhO9SNq3IJyy1MQ3s8P39MhvU=";
|
||||
|
||||
nativeBuildInputs = [ installShellFiles makeWrapper ];
|
||||
|
||||
|
@ -17,6 +17,11 @@ in rec {
|
||||
cp linux-recordreplay.so $out
|
||||
runHook postInstall
|
||||
'';
|
||||
postFixup = ''
|
||||
patchelf --set-rpath "$(patchelf --print-rpath $out):${
|
||||
lib.makeLibraryPath [ openssl ]
|
||||
}" $out
|
||||
'';
|
||||
meta = with lib; {
|
||||
description = "RecordReplay internal recording library";
|
||||
homepage = "https://www.replay.io/";
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"replay": {
|
||||
"url": "https://static.replay.io/downloads/linux-gecko-20220516-372662e7c79d-a9c63f38ea9b.tar.bz2",
|
||||
"sha256": "151k0ykd2mn722zk7n902si6llcsrqnhgjb5bs4wgn9rik9advbi"
|
||||
"url": "https://static.replay.io/downloads/linux-gecko-20220722-71c783507536-b7eae18423ef.tar.bz2",
|
||||
"sha256": "0d3zbiid849nljhpfffi45qy2frghs33s28r86q8xrnli1d0cg83"
|
||||
},
|
||||
"recordreplay": {
|
||||
"url": "https://static.replay.io/downloads/linux-recordreplay-a9c63f38ea9b.tgz",
|
||||
"sha256": "032x9wiw4jcdkn0wjgr5j3pc4parrdy5n4r8bgmfxsldg5j48hmk",
|
||||
"url": "https://static.replay.io/downloads/linux-recordreplay-b7eae18423ef.tgz",
|
||||
"sha256": "1nvhka6ryiw8hac2fkg6va1narb0d7jiqqhxgs1dzblian3kw5j3",
|
||||
"stripRoot": false
|
||||
},
|
||||
"replay-node": {
|
||||
"url": "https://static.replay.io/downloads/linux-node-20220506-096c12cb47eb-a1d05f422dff",
|
||||
"sha256": "1fbqlx01vp6llbvvz285brmz86jxc989v0cw6s06jk0657g87inq"
|
||||
"url": "https://static.replay.io/downloads/linux-node-20220726-bac6d66b5ca1-5b966f2f136c",
|
||||
"sha256": "1563bypnh60wd3k4s5xkla10cymyvnzcl4cfnkpyyrv5920qqc19"
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "kamid";
|
||||
version = "0.1";
|
||||
version = "0.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/omar-polo/kamid/releases/download/${version}/${pname}-${version}.tar.gz";
|
||||
sha256 = "16gi82dgaxwy8fgg05hbam796pk51i6xlyrx8qhghi7ikxr5jd19";
|
||||
sha256 = "sha256-23LgcZ+R6wcUz1fZA+IbhyshfQOTyiFPZ+uKVwOh680=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -2,16 +2,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "microserver";
|
||||
version = "0.2.0";
|
||||
version = "0.2.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "robertohuertasm";
|
||||
repo = "microserver";
|
||||
rev = "v${version}";
|
||||
sha256 = "1bbbdajh74wh2fbidasim2mzmzqjrgi02v8b0g7vbhpdnlim6ixz";
|
||||
sha256 = "sha256-VgzOdJ1JLe0acjRYvaysCPox5acFmc4VD2f6HZWxT8M=";
|
||||
};
|
||||
|
||||
cargoSha256 = "1wh5riw1fr87wbzbzjnwi5zsc5nflwnp6qcpa8a2js54ncd01n16";
|
||||
cargoSha256 = "sha256-JGsMtlWuww1rYE4w6i2VlyD6gGHqnLehLDZmW57R+Fo=";
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security ]);
|
||||
|
||||
|
87
pkgs/servers/web-apps/outline/default.nix
Normal file
87
pkgs/servers/web-apps/outline/default.nix
Normal file
@ -0,0 +1,87 @@
|
||||
{ stdenv
|
||||
, lib
|
||||
, fetchFromGitHub
|
||||
, makeWrapper
|
||||
, nodejs
|
||||
, yarn
|
||||
, yarn2nix-moretea
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "outline";
|
||||
version = "0.65.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "outline";
|
||||
repo = "outline";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-a9K6nMgg1j93BPiy03M86dDecXv/J47vUaqHH3S6DOs=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper yarn2nix-moretea.fixup_yarn_lock ];
|
||||
buildInputs = [ yarn nodejs ];
|
||||
|
||||
# Replace the inline call to yarn with our sequalize wrapper. This should be
|
||||
# the only occurrence:
|
||||
# https://github.com/outline/outline/search?l=TypeScript&q=yarn
|
||||
patches = [ ./sequelize-command.patch ];
|
||||
|
||||
yarnOfflineCache = yarn2nix-moretea.importOfflineCache ./yarn.nix;
|
||||
|
||||
configurePhase = ''
|
||||
export HOME=$(mktemp -d)/yarn_home
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
yarn config --offline set yarn-offline-mirror $yarnOfflineCache
|
||||
fixup_yarn_lock yarn.lock
|
||||
|
||||
yarn install --offline \
|
||||
--frozen-lockfile \
|
||||
--ignore-engines --ignore-scripts
|
||||
patchShebangs node_modules/
|
||||
yarn build
|
||||
|
||||
pushd server
|
||||
cp -r config migrations onboarding ../build/server/
|
||||
popd
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out/bin $out/share/outline
|
||||
mv node_modules build $out/share/outline/
|
||||
|
||||
node_modules=$out/share/outline/node_modules
|
||||
build=$out/share/outline/build
|
||||
|
||||
makeWrapper ${nodejs}/bin/node $out/bin/outline-server \
|
||||
--add-flags $build/server/index.js \
|
||||
--set NODE_ENV production \
|
||||
--set NODE_PATH $node_modules
|
||||
|
||||
makeWrapper ${nodejs}/bin/node $out/bin/outline-sequelize \
|
||||
--add-flags $node_modules/.bin/sequelize \
|
||||
--add-flags "--migrations-path $build/server/migrations" \
|
||||
--add-flags "--models-path $build/server/models" \
|
||||
--add-flags "--seeders-path $build/server/models/fixtures" \
|
||||
--set NODE_ENV production \
|
||||
--set NODE_PATH $node_modules
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "The fastest wiki and knowledge base for growing teams. Beautiful, feature rich, and markdown compatible";
|
||||
homepage = "https://www.getoutline.com/";
|
||||
changelog = "https://github.com/outline/outline/releases";
|
||||
license = licenses.bsl11;
|
||||
maintainers = with maintainers; [ cab404 yrd ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
15
pkgs/servers/web-apps/outline/sequelize-command.patch
Normal file
15
pkgs/servers/web-apps/outline/sequelize-command.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/server/utils/startup.ts b/server/utils/startup.ts
|
||||
index 7554b854..6641f805 100644
|
||||
--- a/server/utils/startup.ts
|
||||
+++ b/server/utils/startup.ts
|
||||
@@ -8,9 +8,7 @@ import Team from "@server/models/Team";
|
||||
export function checkPendingMigrations() {
|
||||
try {
|
||||
const commandResult = execSync(
|
||||
- `yarn sequelize db:migrate:status${
|
||||
- env.PGSSLMODE === "disable" ? " --env=production-ssl-disabled" : ""
|
||||
- }`
|
||||
+ "outline-sequelize db:migrate:status"
|
||||
);
|
||||
const commandResultArray = Buffer.from(commandResult)
|
||||
.toString("utf-8")
|
15728
pkgs/servers/web-apps/outline/yarn.lock
Normal file
15728
pkgs/servers/web-apps/outline/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
16909
pkgs/servers/web-apps/outline/yarn.nix
Normal file
16909
pkgs/servers/web-apps/outline/yarn.nix
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,9 @@ buildGoModule rec {
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-4QNnZHFPyAAQOGRKse4cCc34FgMpelHj+MFTuHLUodE=";
|
||||
};
|
||||
vendorSha256 = "sha256-IO8QOUKTHXeinOW1Wrg2gl2z0u1/TCcPOHmX0G3ONrc=";
|
||||
# hash missmatch on across linux and darwin
|
||||
proxyVendor = true;
|
||||
vendorSha256 = "sha256-Kc7M0wetqAfjoosUYW7v0ZLJ7bb/4z6gG6G83D072Dc=";
|
||||
|
||||
excludedPackages = "misc";
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "instaloader";
|
||||
version = "4.9.2";
|
||||
version = "4.9.3";
|
||||
format = "pyproject";
|
||||
|
||||
disabled = pythonOlder "3.6";
|
||||
@ -16,8 +16,8 @@ buildPythonPackage rec {
|
||||
src = fetchFromGitHub {
|
||||
owner = "instaloader";
|
||||
repo = "instaloader";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-IzOXtoHuKbeHlp4URAlRrSKZ8mRTK7QgsWGd5a99thY=";
|
||||
rev = "refs/tags/v${version}";
|
||||
sha256 = "sha256-lxfnVqAFlMNjtuqtq2iJ2QwPrWskxNCRIAWEwVGr33s=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "mongo-tools";
|
||||
version = "100.5.4";
|
||||
version = "100.6.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mongodb";
|
||||
repo = "mongo-tools";
|
||||
rev = version;
|
||||
sha256 = "sha256-/DbsQh0VinI71ev47hGKfB4PaBlzcOyGHRlmDzW0j7s=";
|
||||
sha256 = "sha256-JSQ8TNStx7rKgmy4cu0C7hVuCG6wA7gpRJru34FJaOo=";
|
||||
};
|
||||
|
||||
vendorSha256 = null;
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "mutt-wizard";
|
||||
version = "3.2.1";
|
||||
version = "3.3.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "LukeSmithxyz";
|
||||
repo = "mutt-wizard";
|
||||
rev = "v${version}";
|
||||
sha256 = "1m4s0vj57hh38rdgdc28p10vnsq80dh708imvdgxbj1i96nq41r8";
|
||||
sha256 = "sha256-1/+awwoAqD8Xm3hULcbpeTaLOHVuYRA4PPr3cq5Gy20=";
|
||||
};
|
||||
|
||||
makeFlags = [ "PREFIX=$(out)" ];
|
||||
|
@ -7,13 +7,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "kdigger";
|
||||
version = "1.2.1";
|
||||
version = "1.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "quarkslab";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-xNOfxJJa0KbrxP1YRDEhnJEmKmpWzXchJWZ/2StR2O0=";
|
||||
sha256 = "sha256-2H7aQoKtNABNI7R01ZOyHCFYUBIu1C7O0snO/i9807o=";
|
||||
# populate values that require us to use git. By doing this in postFetch we
|
||||
# can delete .git afterwards and maintain better reproducibility of the src.
|
||||
leaveDotGit = true;
|
||||
@ -23,7 +23,7 @@ buildGoModule rec {
|
||||
find "$out" -name .git -print0 | xargs -0 rm -rf
|
||||
'';
|
||||
};
|
||||
vendorSha256 = "sha256-3vn3MsE/4lBw89wgYgzm0RuJJ5RQTkgS6O74PpfFcUk=";
|
||||
vendorSha256 = "sha256-Whw8zdfipbWjOXYEAQayfttH0GTTRdJAVjmvLjmsZPw=";
|
||||
|
||||
nativeBuildInputs = [ installShellFiles ];
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "mkp224o";
|
||||
version = "1.5.0";
|
||||
version = "1.6.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cathugger";
|
||||
repo = "mkp224o";
|
||||
rev = "v${version}";
|
||||
sha256 = "0b2cn96wg4l8jkkqqp8l2295xlmm2jc8nrw6rdqb5g0zkpfmrxbb";
|
||||
sha256 = "sha256-+TJ137DmgaFZX+/N6VwXJwfVCoTWtC8NqfXfYJC8UHo=";
|
||||
};
|
||||
|
||||
buildCommand =
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "yubikey-touch-detector";
|
||||
version = "1.9.3";
|
||||
version = "1.10.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "maximbaz";
|
||||
repo = "yubikey-touch-detector";
|
||||
rev = version;
|
||||
sha256 = "sha256-f6j+YNYASH0Adg3236QijApALd/yXJjNMYEdP0Pifw0=";
|
||||
sha256 = "sha256-3tZyaOrNzLfcCORhTSMEu8EvnNUjva8hBNotHgANS0g=";
|
||||
};
|
||||
vendorSha256 = "sha256-H05EJwYDdg4lq6+psXiwujQd5g294epdRPjqviHhLWs=";
|
||||
vendorSha256 = "sha256-OitI9Yp4/mRMrNH4yrWSL785+3mykPkvzarrc6ipOeg=";
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "mdbook-admonish";
|
||||
version = "1.6.0";
|
||||
version = "1.7.0";
|
||||
|
||||
src = fetchCrate {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-GH4T7arBabm+DXIJa3seP6L13DBleoNqYwzxhoCZJgI=";
|
||||
sha256 = "sha256-QvFHpAsQ+S7q/Ye0YEf0phZcVvAs1a80Hd3eIGZBsrI=";
|
||||
};
|
||||
|
||||
cargoSha256 = "sha256-v0usxkGWs/qzUPU6ZwtTpUD7hXdSBZGYQifMZnr7sfI=";
|
||||
cargoSha256 = "sha256-v7MGJlDm5nvydjFAZZS94afZY2OVUjJQ9eXYaY9JxBs=";
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [ CoreServices ];
|
||||
|
||||
|
@ -22874,6 +22874,8 @@ with pkgs;
|
||||
|
||||
onlyoffice-documentserver = callPackage ../servers/onlyoffice-documentserver { };
|
||||
|
||||
outline = callPackage ../servers/web-apps/outline { };
|
||||
|
||||
openbgpd = callPackage ../servers/openbgpd { };
|
||||
|
||||
openafs_1_8 = callPackage ../servers/openafs/1.8 { tsmbac = null; ncurses = null; };
|
||||
|
@ -3281,6 +3281,8 @@ in {
|
||||
|
||||
flask-babelex = callPackage ../development/python-modules/flask-babelex { };
|
||||
|
||||
flask-basicauth = callPackage ../development/python-modules/flask-basicauth { };
|
||||
|
||||
flask-bcrypt = callPackage ../development/python-modules/flask-bcrypt { };
|
||||
|
||||
flask-bootstrap = callPackage ../development/python-modules/flask-bootstrap { };
|
||||
@ -5654,6 +5656,7 @@ in {
|
||||
mkdocs-material-extensions = callPackage ../development/python-modules/mkdocs-material/mkdocs-material-extensions.nix { };
|
||||
mkdocs-minify = callPackage ../development/python-modules/mkdocs-minify { };
|
||||
mkdocs-redirects = callPackage ../development/python-modules/mkdocs-redirects { };
|
||||
mkdocs-swagger-ui-tag = callPackage ../development/python-modules/mkdocs-swagger-ui-tag { };
|
||||
|
||||
mkdocstrings = callPackage ../development/python-modules/mkdocstrings { };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user