@ -312,6 +312,124 @@ in {
phone-numbers .
'' ;
} ;
objectstore = let
s3Arguments = {
bucket = mkOption {
type = types . str ;
example = " n e x t c l o u d " ;
description = ''
The name of the S3 bucket .
'' ;
} ;
autocreate = mkOption {
type = types . bool ;
description = ''
Create the objectstore if it does not exist .
'' ;
} ;
key = mkOption {
type = types . str ;
example = " E J 3 9 I T Y Z E U H 5 B G W D R U F Y " ;
description = ''
The access key for the S3 bucket .
'' ;
} ;
secret = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " M 5 M r X T R j k y M a x X P e 2 F R X M T f T f b K E n Z C u + 7 u R T V S j " ;
description = ''
The access secret for the S3 bucket . Use
<literal> secretFile < /literal > to avoid this being world-readable
in the <literal> /nix/store < /literal >
'' ;
} ;
secretFile = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " / v a r / n e x t c l o u d - o b j e c t s t o r e - s 3 - s e c r e t " ;
description = ''
The full path to a file that contains the access secret . Must be
readable by user <literal> nextcloud < /literal > .
'' ;
} ;
hostname = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " e x a m p l e . c o m " ;
description = ''
Required for some non-Amazon implementations .
'' ;
} ;
port = mkOption {
type = types . nullOr types . port ;
default = null ;
description = ''
Required for some non-Amazon implementations .
'' ;
} ;
useSsl = mkOption {
type = types . nullOr types . bool ;
default = null ;
description = ''
Use SSL for objectstore access .
'' ;
} ;
region = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " R E G I O N " ;
description = ''
Required for some non-Amazon implementations .
'' ;
} ;
usePathStyle = mkOption {
type = types . bool ;
default = false ;
description = ''
Required for some non-Amazon S3 implementations .
Ordinarily , requests will be made with
http://bucket.hostname.domain/, but with path style
enabled requests are made with
http://hostname.domain/bucket instead .
'' ;
} ;
} ;
in mkOption {
type = types . nullOr ( types . submodule {
options = {
s3 = mkOption {
type = types . submodule {
options = {
enable = mkEnableOption " S 3 o b j e c t s t o r a g e a s p r i m a r y s t o r a g e . " ;
arguments = mkOption {
type = types . submodule {
options = s3Arguments ;
} ;
description = ''
Configuration arguments for the object storage .
'' ;
} ;
} ;
} ;
description = ''
Mounts a bucket on an Amazon S3 object storage or compatible
implementation into the virtual filesystem .
'' ;
} ;
} ;
} ) ;
default = null ;
description = ''
Options for configuring object storage as nextcloud's primary storage .
See nextcloud's documentation on " O b j e c t S t o r a g e a s P r i m a r y S t o r a g e "
for details on how to select the right class and argument set for
your needs .
'' ;
} ;
} ;
enableImagemagick = mkEnableOption ''
@ -390,6 +508,14 @@ in {
{ assertion = versionOlder cfg . package . version " 2 1 " -> cfg . config . defaultPhoneRegion == null ;
message = " T h e ` d e f a u l t P h o n e R e g i o n ' - s e t t i n g i s o n l y s u p p o r t e d f o r N e x t c l o u d > = 2 1 ! " ;
}
{ assertion = acfg . objectstore == null
|| ( lists . count ( v : v . enable ) ( attrsets . attrValues acfg . objectstore ) ) == 1 ;
message = " I f u s i n g o b j e c t s t o r e c l a s s a s p r i m a r y s t o r a g e e x a c t l y o n e c l a s s c a n b e e n a b l e d . " ;
}
{ assertion = let s3 = acfg . objectstore . s3 ; in acfg . objectstore == null
|| ( ! s3 . enable || ( ( s3 . arguments . secret != null ) != ( s3 . arguments . secretFile != null ) ) ) ;
message = " S 3 s t o r a g e r e q u i r e s s p e c i f y i n g e x a c t l y o n e o f s e c r e t o r s e c r e t F i l e " ;
}
] ;
warnings = let
@ -479,11 +605,34 @@ in {
nextcloud-setup = let
c = cfg . config ;
writePhpArrary = a : " [ ${ concatMapStringsSep " , " ( val : '' " ${ toString val } " '' ) a } ] " ;
requiresReadSecretFunction = c . dbpassFile != null
|| ( c . objectstore != null && ( c . objectstore . s3 . enable && c . objectstore . s3 . arguments . secretFile != null ) ) ;
objectstoreConfig = let
class = if c . objectstore . s3 . enable then " S 3 " else " " ;
args = if c . objectstore . s3 . enable then c . objectstore . s3 . arguments else { } ;
classLine = '' ' c l a s s ' = > ' \ \ O C \ \ F i l e s \ \ O b j e c t S t o r e \ \ ${ class } ' , '' ;
argumentLines = optionalString c . objectstore . s3 . enable ''
' bucket' = > ' $ { args . bucket } ' ,
' autocreate' = > $ { toString args . autocreate } ,
' key' = > ' $ { args . key } ' ,
$ { optionalString ( args . secret != null ) " ' s e c r e t ' = > ' ${ args . secret } ' , " }
$ { optionalString ( args . secretFile != null ) " ' s e c r e t ' = > n i x _ r e a d _ s e c r e t ( ' ${ args . secretFile } ' ) , " }
$ { optionalString ( args . hostname != null ) " ' h o s t n a m e ' = > ' ${ args . hostname } ' , " }
$ { optionalString ( args . port != null ) " ' p o r t ' = > ${ toString args . port } , " }
$ { optionalString ( args . useSsl != null ) " ' u s e _ s s l ' = > ${ if args . useSsl then " t r u e " else " f a l s e " } , " }
$ { optionalString ( args . region != null ) " ' r e g i o n ' = > ' ${ args . region } ' , " }
' use_path_style' = > $ { if args . usePathStyle then " t r u e " else " f a l s e " } ,
'' ;
in optionalString ( c . objectstore != null ) '' ' o b j e c t s t o r e ' = > [
$ { classLine }
' arguments' = > [
$ { argumentLines }
] ,
] '' ;
overrideConfig = pkgs . writeText " n e x t c l o u d - c o n f i g . p h p " ''
< ? php
$ { optionalString ( c . dbpassFile != null ) ''
function nix_read_pwd ( ) {
$ file = " ${ c . dbpassFile } " ;
$ { optionalString requiresReadSecretFunction ''
function nix_read_secret ( $ file ) {
if ( ! file_exists ( $ file ) ) {
throw new \ RuntimeException ( sprintf (
" C a n n o t s t a r t N e x t c l o u d , d b p a s s f i l e % s s e t b y N i x O S d o e s n ' t s e e m t o "
@ -513,11 +662,12 @@ in {
$ { optionalString ( c . dbuser != null ) " ' d b u s e r ' = > ' ${ c . dbuser } ' , " }
$ { optionalString ( c . dbtableprefix != null ) " ' d b t a b l e p r e f i x ' = > ' ${ toString c . dbtableprefix } ' , " }
$ { optionalString ( c . dbpass != null ) " ' d b p a s s w o r d ' = > ' ${ c . dbpass } ' , " }
$ { optionalString ( c . dbpassFile != null ) " ' d b p a s s w o r d ' = > n i x _ r e a d _ p w d ( ) , " }
$ { optionalString ( c . dbpassFile != null ) " ' d b p a s s w o r d ' = > n i x _ r e a d _ s e c r e t ( ' ${ c . dbpassFile } ' ) , " }
' dbtype' = > ' $ { c . dbtype } ' ,
' trusted_domains' = > $ { writePhpArrary ( [ cfg . hostName ] ++ c . extraTrustedDomains ) } ,
' trusted_proxies' = > $ { writePhpArrary ( c . trustedProxies ) } ,
$ { optionalString ( c . defaultPhoneRegion != null ) " ' d e f a u l t _ p h o n e _ r e g i o n ' = > ' ${ c . defaultPhoneRegion } ' , " }
$ { objectstoreConfig }
] ;
'' ;
occInstallCmd = let