commit
249398ffa8
@ -1,2 +1,2 @@ |
||||
# Expose the minimum required version for evaluating Nixpkgs |
||||
"2.2" |
||||
"2.3" |
||||
|
@ -0,0 +1,64 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.netbird; |
||||
kernel = config.boot.kernelPackages; |
||||
interfaceName = "wt0"; |
||||
in { |
||||
meta.maintainers = with maintainers; [ misuzu ]; |
||||
|
||||
options.services.netbird = { |
||||
enable = mkEnableOption "Netbird daemon"; |
||||
package = mkOption { |
||||
type = types.package; |
||||
default = pkgs.netbird; |
||||
defaultText = literalExpression "pkgs.netbird"; |
||||
description = "The package to use for netbird"; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf cfg.enable { |
||||
boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard; |
||||
|
||||
environment.systemPackages = [ cfg.package ]; |
||||
|
||||
networking.dhcpcd.denyInterfaces = [ interfaceName ]; |
||||
|
||||
systemd.network.networks."50-netbird" = mkIf config.networking.useNetworkd { |
||||
matchConfig = { |
||||
Name = interfaceName; |
||||
}; |
||||
linkConfig = { |
||||
Unmanaged = true; |
||||
ActivationPolicy = "manual"; |
||||
}; |
||||
}; |
||||
|
||||
systemd.services.netbird = { |
||||
description = "A WireGuard-based mesh network that connects your devices into a single private network"; |
||||
documentation = [ "https://netbird.io/docs/" ]; |
||||
after = [ "network.target" ]; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
serviceConfig = { |
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ]; |
||||
DynamicUser = true; |
||||
Environment = [ |
||||
"NB_CONFIG=/var/lib/netbird/config.json" |
||||
"NB_LOG_FILE=console" |
||||
]; |
||||
ExecStart = "${cfg.package}/bin/netbird service run"; |
||||
Restart = "always"; |
||||
RuntimeDirectory = "netbird"; |
||||
StateDirectory = "netbird"; |
||||
WorkingDirectory = "/var/lib/netbird"; |
||||
}; |
||||
unitConfig = { |
||||
StartLimitInterval = 5; |
||||
StartLimitBurst = 10; |
||||
}; |
||||
stopIfChanged = false; |
||||
}; |
||||
}; |
||||
} |
@ -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"; |
||||
}; |
||||
}; |
||||
}; |
||||
} |
@ -0,0 +1,49 @@ |
||||
import ./make-test-python.nix ({ pkgs, ... }: { |
||||
name = "libvirtd"; |
||||
meta.maintainers = with pkgs.lib.maintainers; [ fpletz ]; |
||||
|
||||
nodes = { |
||||
virthost = |
||||
{ pkgs, ... }: |
||||
{ |
||||
virtualisation = { |
||||
cores = 2; |
||||
memorySize = 2048; |
||||
|
||||
libvirtd.enable = true; |
||||
}; |
||||
networking.nameservers = [ "192.168.122.1" ]; |
||||
security.polkit.enable = true; |
||||
environment.systemPackages = with pkgs; [ virt-manager ]; |
||||
}; |
||||
}; |
||||
|
||||
testScript = let |
||||
nixosInstallISO = (import ../release.nix {}).iso_minimal.${pkgs.hostPlatform.system}; |
||||
virshShutdownCmd = if pkgs.stdenv.isx86_64 then "shutdown" else "destroy"; |
||||
in '' |
||||
start_all() |
||||
|
||||
virthost.wait_for_unit("sockets.target") |
||||
|
||||
with subtest("enable default network"): |
||||
virthost.succeed("virsh net-start default") |
||||
virthost.succeed("virsh net-autostart default") |
||||
virthost.succeed("virsh net-info default") |
||||
|
||||
with subtest("check if partition disk pools works with parted"): |
||||
virthost.succeed("fallocate -l100m /tmp/foo; losetup /dev/loop0 /tmp/foo; echo 'label: dos' | sfdisk /dev/loop0") |
||||
virthost.succeed("virsh pool-create-as foo disk --source-dev /dev/loop0 --target /dev") |
||||
virthost.succeed("virsh vol-create-as foo loop0p1 25MB") |
||||
virthost.succeed("virsh vol-create-as foo loop0p2 50MB") |
||||
|
||||
with subtest("check if nixos install iso boots and network works"): |
||||
virthost.succeed( |
||||
"virt-install -n nixos --osinfo=nixos-unstable --ram=1024 --graphics=none --disk=`find ${nixosInstallISO}/iso -type f | head -n1`,readonly=on --import --noautoconsole" |
||||
) |
||||
virthost.succeed("virsh domstate nixos | grep running") |
||||
virthost.wait_until_succeeds("ping -c 1 nixos") |
||||
virthost.succeed("virsh ${virshShutdownCmd} nixos") |
||||
virthost.wait_until_succeeds("virsh domstate nixos | grep 'shut off'") |
||||
''; |
||||
}) |
@ -0,0 +1,21 @@ |
||||
import ./make-test-python.nix ({ pkgs, lib, ... }: |
||||
{ |
||||
name = "netbird"; |
||||
|
||||
meta = with pkgs.lib.maintainers; { |
||||
maintainers = [ misuzu ]; |
||||
}; |
||||
|
||||
nodes = { |
||||
node = { ... }: { |
||||
services.netbird.enable = true; |
||||
}; |
||||
}; |
||||
|
||||
testScript = '' |
||||
start_all() |
||||
node.wait_for_unit("netbird.service") |
||||
node.wait_for_file("/var/run/netbird/sock") |
||||
node.succeed("netbird status | grep -q 'Daemon status: NeedsLogin'") |
||||
''; |
||||
}) |
@ -0,0 +1,107 @@ |
||||
{ stdenv |
||||
, lib |
||||
, fetchFromGitHub |
||||
, cmake |
||||
, pkg-config |
||||
, libX11 |
||||
, libXrandr |
||||
, libXinerama |
||||
, libXext |
||||
, libXcursor |
||||
, freetype |
||||
, alsa-lib |
||||
, libjack2 |
||||
, Cocoa |
||||
, WebKit |
||||
, MetalKit |
||||
, simd |
||||
, DiscRecording |
||||
, CoreAudioKit |
||||
}: |
||||
|
||||
stdenv.mkDerivation rec { |
||||
pname = "dexed"; |
||||
version = "unstable-2022-07-09"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "asb2m10"; |
||||
repo = "dexed"; |
||||
rev = "2c036316bcd512818aa9cc8129767ad9e0ec7132"; |
||||
fetchSubmodules = true; |
||||
sha256 = "sha256-6buvA72YRlGjHWLPEZMr45lYYG6ZY+IWmylcHruX27g="; |
||||
}; |
||||
|
||||
postPatch = '' |
||||
# needs special setup on Linux, dunno if it can work on Darwin |
||||
# https://github.com/NixOS/nixpkgs/issues/19098 |
||||
sed -i -e '/juce::juce_recommended_lto_flags/d' Source/CMakeLists.txt |
||||
''; |
||||
|
||||
nativeBuildInputs = [ |
||||
cmake |
||||
pkg-config |
||||
]; |
||||
|
||||
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ |
||||
libX11 |
||||
libXext |
||||
libXcursor |
||||
libXinerama |
||||
libXrandr |
||||
freetype |
||||
alsa-lib |
||||
libjack2 |
||||
] ++ lib.optionals stdenv.hostPlatform.isDarwin [ |
||||
Cocoa |
||||
WebKit |
||||
MetalKit |
||||
simd |
||||
DiscRecording |
||||
CoreAudioKit |
||||
]; |
||||
|
||||
# JUCE insists on only dlopen'ing these |
||||
NIX_LDFLAGS = lib.optionalString stdenv.hostPlatform.isLinux (toString [ |
||||
"-lX11" |
||||
"-lXext" |
||||
"-lXcursor" |
||||
"-lXinerama" |
||||
"-lXrandr" |
||||
"-ljack" |
||||
]); |
||||
|
||||
installPhase = let |
||||
vst3Dir = if stdenv.hostPlatform.isDarwin then "$out/Library/Audio/Plug-Ins/VST3" else "$out/lib/vst3"; |
||||
# this one's a guess, don't know where ppl have agreed to put them yet |
||||
clapDir = if stdenv.hostPlatform.isDarwin then "$out/Library/Audio/Plug-Ins/CLAP" else "$out/lib/clap"; |
||||
auDir = "$out/Library/Audio/Plug-Ins/Components"; |
||||
in '' |
||||
runHook preInstall |
||||
|
||||
'' + (if stdenv.hostPlatform.isDarwin then '' |
||||
mkdir -p $out/{Applications,bin} |
||||
mv Source/Dexed_artefacts/Release/Standalone/Dexed.app $out/Applications/ |
||||
ln -s $out/{Applications/Dexed.app/Contents/MacOS,bin}/Dexed |
||||
'' else '' |
||||
install -Dm755 {Source/Dexed_artefacts/Release/Standalone,$out/bin}/Dexed |
||||
'') + '' |
||||
mkdir -p ${vst3Dir} ${clapDir} |
||||
mv Source/Dexed_artefacts/Release/VST3/* ${vst3Dir} |
||||
mv Source/Dexed_artefacts/Release/CLAP/* ${clapDir} |
||||
'' + lib.optionalString stdenv.hostPlatform.isDarwin '' |
||||
mkdir -p ${auDir} |
||||
mv Source/Dexed_artefacts/Release/AU/* ${auDir} |
||||
'' + '' |
||||
|
||||
runHook postInstall |
||||
''; |
||||
|
||||
meta = with lib; { |
||||
description = "DX7 FM multi platform/multi format plugin"; |
||||
mainProgram = "Dexed"; |
||||
homepage = "https://asb2m10.github.io/dexed"; |
||||
license = licenses.gpl3Only; |
||||
platforms = platforms.all; |
||||
maintainers = with maintainers; [ OPNA2608 ]; |
||||
}; |
||||
} |
@ -0,0 +1,71 @@ |
||||
{ stdenv |
||||
, lib |
||||
, fetchFromGitHub |
||||
, buildGoModule |
||||
, wrapGAppsHook |
||||
, pkg-config |
||||
, glib |
||||
, gobject-introspection |
||||
, gtk3 |
||||
, gdk-pixbuf |
||||
, gettext |
||||
, librsvg |
||||
}: |
||||
|
||||
buildGoModule rec { |
||||
pname = "ymuse"; |
||||
version = "0.20"; |
||||
|
||||
src = fetchFromGitHub { |
||||
owner = "yktoo"; |
||||
repo = "ymuse"; |
||||
rev = "v${version}"; |
||||
sha256 = "sha256-wDQjNBxwxFVFdSswubp4AVD35aXKJ8i0ahk/tgRsDRc="; |
||||
}; |
||||
vendorSha256 = "sha256-Ap/nf0NT0VkP2k9U1HzEiptDfLjKkBopP5h0czP3vis="; |
||||
|
||||
nativeBuildInputs = [ |
||||
pkg-config |
||||
wrapGAppsHook |
||||
glib |
||||
gobject-introspection |
||||
gdk-pixbuf |
||||
gettext |
||||
]; |
||||
|
||||
buildInputs = [ |
||||
gtk3 |
||||
librsvg |
||||
]; |
||||
|
||||
postInstall = '' |
||||
install -Dm644 ./resources/ymuse.desktop -t $out/share/applications |
||||
cp -r ./resources/icons $out/share |
||||
|
||||
app_id="ymuse" |
||||
find ./resources/i18n -type f -name '*.po' | |
||||
while read file; do |
||||
# Language is the filename without the extension |
||||
lang="$(basename "$file")" |
||||
lang="''${lang%.*}" |
||||
|
||||
# Create the target dir if needed |
||||
target_dir="$out/share/locale/$lang/LC_MESSAGES" |
||||
mkdir -p "$target_dir" |
||||
|
||||
# Compile the .po into a .mo |
||||
echo "Compiling $file" into "$target_dir/$app_id.mo" |
||||
msgfmt "$file" -o "$target_dir/$app_id.mo" |
||||
done |
||||
''; |
||||
|
||||
# IDK how to deal with tests that open up display. |
||||
doCheck = false; |
||||
|
||||
meta = with lib; { |
||||
homepage = "https://yktoo.com/en/software/ymuse/"; |
||||
description = "GTK client for Music Player Daemon (MPD)"; |
||||
license = licenses.asl20; |
||||
maintainers = with maintainers; [ foo-dogsquared ]; |
||||
}; |
||||
} |
@ -0,0 +1,3 @@ |
||||
map <Leader>$ <Cmd>Obsession<CR> |
||||
" placeholder config |
||||
" just a comment |
File diff suppressed because it is too large
Load Diff
@ -1,84 +1,105 @@ |
||||
#! /usr/bin/env nix-shell |
||||
#! nix-shell -i bash -p nix nix-prefetch-git coreutils curl jq gnused |
||||
#! nix-shell -I nixpkgs=./. -i bash -p nix nix-prefetch-git coreutils curl jq gnused |
||||
|
||||
set -e |
||||
set -euo pipefail |
||||
|
||||
# Will be replaced with the actual branch when running this from passthru.updateScript |
||||
BRANCH="@branch@" |
||||
DEFAULT_NIX="$(dirname "${BASH_SOURCE[@]}")/default.nix" |
||||
|
||||
if [[ ! "$(basename $PWD)" = "yuzu" ]]; then |
||||
echo "error: Script must be ran from yuzu's directory!" |
||||
if [[ "$(basename "$PWD")" = "yuzu" ]]; then |
||||
echo "error: Script must be ran from nixpkgs's root directory for compatibility with the maintainer script" |
||||
exit 1 |
||||
fi |
||||
|
||||
getLocalVersion() { |
||||
pushd ../../../.. >/dev/null |
||||
nix eval --raw -f default.nix "$1".version |
||||
popd >/dev/null |
||||
} |
||||
|
||||
getLocalHash() { |
||||
pushd ../../../.. >/dev/null |
||||
nix eval --raw -f default.nix "$1".src.drvAttrs.outputHash |
||||
popd >/dev/null |
||||
} |
||||
|
||||
updateMainline() { |
||||
OLD_MAINLINE_VERSION="$(getLocalVersion "yuzu-mainline")" |
||||
OLD_MAINLINE_HASH="$(getLocalHash "yuzu-mainline")" |
||||
|
||||
NEW_MAINLINE_VERSION="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} \ |
||||
"https://api.github.com/repos/yuzu-emu/yuzu-mainline/releases?per_page=1" | jq -r '.[0].name' | cut -d" " -f2)" |
||||
|
||||
if [[ "${OLD_MAINLINE_VERSION}" = "${NEW_MAINLINE_VERSION}" ]]; then |
||||
echo "yuzu-mainline is already up to date!" |
||||
updateBranch() { |
||||
local branch attribute oldVersion oldHash newVersion newHash |
||||
branch="$1" |
||||
attribute="yuzu-$branch" |
||||
[[ "$branch" = "early-access" ]] && attribute="yuzu-ea" # Attribute path doesnt match the branch name |
||||
oldVersion="$(nix eval --raw -f "./default.nix" "$attribute".version)" |
||||
oldHash="$(nix eval --raw -f "./default.nix" "$attribute".src.drvAttrs.outputHash)" |
||||
|
||||
if [[ "$branch" = "mainline" ]]; then |
||||
newVersion="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/yuzu-emu/yuzu-mainline/releases?per_page=1" \ |
||||
| jq -r '.[0].name' | cut -d" " -f2)" |
||||
elif [[ "$branch" = "early-access" ]]; then |
||||
newVersion="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/pineappleEA/pineapple-src/releases?per_page=2" \ |
||||
| jq -r '.[].tag_name' | grep '^EA-[0-9]*' | head -n1 | cut -d"-" -f2 | cut -d" " -f1)" |
||||
fi |
||||
|
||||
[ "$KEEP_GOING" ] && return || exit |
||||
if [[ "${oldVersion}" = "${newVersion}" ]]; then |
||||
echo "$attribute is already up to date." |
||||
return |
||||
else |
||||
echo "yuzu-mainline: ${OLD_MAINLINE_VERSION} -> ${NEW_MAINLINE_VERSION}" |
||||
echo "$attribute: ${oldVersion} -> ${newVersion}" |
||||
fi |
||||
|
||||
echo " Fetching source code..." |
||||
|
||||
NEW_MAINLINE_HASH="$(nix-prefetch-git --quiet --fetch-submodules --rev "mainline-0-${NEW_MAINLINE_VERSION}" "https://github.com/yuzu-emu/yuzu-mainline" | jq -r '.sha256')" |
||||
|
||||
echo " Succesfully fetched. hash: ${NEW_MAINLINE_HASH}" |
||||
echo " fetching source code to generate hash..." |
||||
if [[ "$branch" = "mainline" ]]; then |
||||
newHash="$(nix-prefetch-git --quiet --fetch-submodules --rev "mainline-0-${newVersion}" "https://github.com/yuzu-emu/yuzu-mainline" | jq -r '.sha256')" |
||||
elif [[ "$branch" = "early-access" ]]; then |
||||
newHash="$(nix-prefetch-git --quiet --fetch-submodules --rev "EA-${newVersion}" "https://github.com/pineappleEA/pineapple-src" | jq -r '.sha256')" |
||||
fi |
||||
newHash="$(nix hash to-sri --type sha256 "${newHash}")" |
||||
|
||||
sed -i "s/${OLD_MAINLINE_VERSION}/${NEW_MAINLINE_VERSION}/" ./default.nix |
||||
sed -i "s/${OLD_MAINLINE_HASH}/${NEW_MAINLINE_HASH}/" ./default.nix |
||||
sed -i "s,${oldVersion},${newVersion}," "$DEFAULT_NIX" |
||||
sed -i "s,${oldHash},${newHash},g" "$DEFAULT_NIX" |
||||
echo " succesfully updated $attribute. new hash: $newHash" |
||||
} |
||||
|
||||
updateEarlyAccess() { |
||||
OLD_EA_VERSION="$(getLocalVersion "yuzu-ea")" |
||||
OLD_EA_HASH="$(getLocalHash "yuzu-ea")" |
||||
updateCompatibilityList() { |
||||
local latestRevision oldUrl newUrl oldHash newHash oldDate newDate |
||||
latestRevision="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/flathub/org.yuzu_emu.yuzu/commits/master" | jq -r '.sha')" |
||||
|
||||
NEW_EA_VERSION="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} \ |
||||
"https://api.github.com/repos/pineappleEA/pineapple-src/releases?per_page=2" | jq -r '.[].tag_name' | grep '^EA-[0-9]*' | head -n1 | cut -d"-" -f2 | cut -d" " -f1)" |
||||
oldUrl="$(sed -n '/yuzu-compat-list/,/url/p' "$DEFAULT_NIX" | tail -n1 | cut -d'"' -f2)" |
||||
newUrl="https://raw.githubusercontent.com/flathub/org.yuzu_emu.yuzu/${latestRevision}/compatibility_list.json" |
||||
|
||||
if [[ "${OLD_EA_VERSION}" = "${NEW_EA_VERSION}" ]]; then |
||||
echo "yuzu-ea is already up to date!" |
||||
oldDate="$(sed -n '/last updated.*/p' "$DEFAULT_NIX" | rev | cut -d' ' -f1 | rev)" |
||||
newDate="$(curl -s ${GITHUB_TOKEN:+"-u \":$GITHUB_TOKEN\""} "https://api.github.com/repos/flathub/org.yuzu_emu.yuzu/commits/${latestRevision}" \ |
||||
| jq -r '.commit.committer.date' | cut -d'T' -f1)" |
||||
|
||||
[ "$KEEP_GOING" ] && return || exit |
||||
oldHash="$(sed -n '/yuzu-compat-list/,/sha256/p' "$DEFAULT_NIX" | tail -n1 | cut -d'"' -f2)" |
||||
newHash="$(nix hash to-sri --type sha256 "$(nix-prefetch-url --quiet "$newUrl")")" |
||||
|
||||
if [[ "$oldHash" = "$newHash" ]]; then |
||||
echo "compatibility_list is already up to date." |
||||
return |
||||
else |
||||
echo "yuzu-ea: ${OLD_EA_VERSION} -> ${NEW_EA_VERSION}" |
||||
echo "compatibility_list: $oldDate -> $newDate" |
||||
fi |
||||
|
||||
echo " Fetching source code..." |
||||
|
||||
NEW_EA_HASH="$(nix-prefetch-git --quiet --fetch-submodules --rev "EA-${NEW_EA_VERSION}" "https://github.com/pineappleEA/pineapple-src" | jq -r '.sha256')" |
||||
|
||||
echo " Succesfully fetched. hash: ${NEW_EA_HASH}" |
||||
|
||||
sed -i "s/${OLD_EA_VERSION}/${NEW_EA_VERSION}/" ./default.nix |
||||
sed -i "s/${OLD_EA_HASH}/${NEW_EA_HASH}/" ./default.nix |
||||
sed -i "s,${oldUrl},${newUrl},g" "$DEFAULT_NIX" |
||||
sed -i "s,${oldHash},${newHash},g" "$DEFAULT_NIX" |
||||
sed -i "s,${oldDate},${newDate},g" "$DEFAULT_NIX" |
||||
echo " succesfully updated compatibility_list. new hash: $newHash" |
||||
} |
||||
|
||||
if [[ "$BRANCH" = "mainline" ]]; then |
||||
updateMainline |
||||
elif [[ "$BRANCH" = "early-access" ]]; then |
||||
updateEarlyAccess |
||||
else |
||||
KEEP_GOING=1 |
||||
updateMainline |
||||
updateEarlyAccess |
||||
if [[ "$BRANCH" = "mainline" ]] || [[ "$BRANCH" = "early-access" ]]; then |
||||
updateBranch "$BRANCH" |
||||
updateCompatibilityList |
||||
else # Script is not ran from passthru.updateScript |
||||
if (( $# == 0 )); then |
||||
updateBranch "mainline" |
||||
updateBranch "early-access" |
||||
fi |
||||
|
||||
while (( "$#" > 0 )); do |
||||
case "$1" in |
||||
mainline|yuzu-mainline) |
||||
updateBranch "mainline" |
||||
;; |
||||
early-access|yuzu-early-access|ea|yuzu-ea) |
||||
updateBranch "early-access" |
||||
;; |
||||
*) |
||||
echo "error: invalid branch: $1." |
||||
echo "usage: $(basename "$0") [mainline|early-access]" |
||||
exit 1 |
||||
;; |
||||
esac |
||||
shift |
||||
done |
||||
|
||||
updateCompatibilityList |
||||
fi |
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue