nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 954 lines 29 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.athens; 9 10 athensConfig = lib.flip lib.recursiveUpdate cfg.extraConfig { 11 GoBinary = "${cfg.goBinary}/bin/go"; 12 GoEnv = cfg.goEnv; 13 GoBinaryEnvVars = lib.mapAttrsToList (k: v: "${k}=${v}") cfg.goBinaryEnvVars; 14 GoGetWorkers = cfg.goGetWorkers; 15 GoGetDir = cfg.goGetDir; 16 ProtocolWorkers = cfg.protocolWorkers; 17 LogLevel = cfg.logLevel; 18 CloudRuntime = cfg.cloudRuntime; 19 EnablePprof = cfg.enablePprof; 20 PprofPort = ":${toString cfg.pprofPort}"; 21 FilterFile = cfg.filterFile; 22 RobotsFile = cfg.robotsFile; 23 Timeout = cfg.timeout; 24 StorageType = cfg.storageType; 25 TLSCertFile = cfg.tlsCertFile; 26 TLSKeyFile = cfg.tlsKeyFile; 27 Port = ":${toString cfg.port}"; 28 UnixSocket = cfg.unixSocket; 29 GlobalEndpoint = cfg.globalEndpoint; 30 BasicAuthUser = cfg.basicAuthUser; 31 BasicAuthPass = cfg.basicAuthPass; 32 ForceSSL = cfg.forceSSL; 33 ValidatorHook = cfg.validatorHook; 34 PathPrefix = cfg.pathPrefix; 35 NETRCPath = cfg.netrcPath; 36 GithubToken = cfg.githubToken; 37 HGRCPath = cfg.hgrcPath; 38 TraceExporter = cfg.traceExporter; 39 StatsExporter = cfg.statsExporter; 40 SumDBs = cfg.sumDBs; 41 NoSumPatterns = cfg.noSumPatterns; 42 DownloadMode = cfg.downloadMode; 43 NetworkMode = cfg.networkMode; 44 DownloadURL = cfg.downloadURL; 45 SingleFlightType = cfg.singleFlightType; 46 IndexType = cfg.indexType; 47 ShutdownTimeout = cfg.shutdownTimeout; 48 SingleFlight = { 49 Etcd = { 50 Endpoints = builtins.concatStringsSep "," cfg.singleFlight.etcd.endpoints; 51 }; 52 Redis = { 53 Endpoint = cfg.singleFlight.redis.endpoint; 54 Password = cfg.singleFlight.redis.password; 55 LockConfig = { 56 TTL = cfg.singleFlight.redis.lockConfig.ttl; 57 Timeout = cfg.singleFlight.redis.lockConfig.timeout; 58 MaxRetries = cfg.singleFlight.redis.lockConfig.maxRetries; 59 }; 60 }; 61 RedisSentinel = { 62 Endpoints = cfg.singleFlight.redisSentinel.endpoints; 63 MasterName = cfg.singleFlight.redisSentinel.masterName; 64 SentinelPassword = cfg.singleFlight.redisSentinel.sentinelPassword; 65 LockConfig = { 66 TTL = cfg.singleFlight.redisSentinel.lockConfig.ttl; 67 Timeout = cfg.singleFlight.redisSentinel.lockConfig.timeout; 68 MaxRetries = cfg.singleFlight.redisSentinel.lockConfig.maxRetries; 69 }; 70 }; 71 }; 72 Storage = { 73 CDN = { 74 Endpoint = cfg.storage.cdn.endpoint; 75 }; 76 Disk = { 77 RootPath = cfg.storage.disk.rootPath; 78 }; 79 GCP = { 80 ProjectID = cfg.storage.gcp.projectID; 81 Bucket = cfg.storage.gcp.bucket; 82 JSONKey = cfg.storage.gcp.jsonKey; 83 }; 84 Mongo = { 85 URL = cfg.storage.mongo.url; 86 DefaultDBName = cfg.storage.mongo.defaultDBName; 87 CertPath = cfg.storage.mongo.certPath; 88 Insecure = cfg.storage.mongo.insecure; 89 }; 90 S3 = { 91 Region = cfg.storage.s3.region; 92 Key = cfg.storage.s3.key; 93 Secret = cfg.storage.s3.secret; 94 Token = cfg.storage.s3.token; 95 Bucket = cfg.storage.s3.bucket; 96 ForcePathStyle = cfg.storage.s3.forcePathStyle; 97 UseDefaultConfiguration = cfg.storage.s3.useDefaultConfiguration; 98 CredentialsEndpoint = cfg.storage.s3.credentialsEndpoint; 99 AwsContainerCredentialsRelativeURI = cfg.storage.s3.awsContainerCredentialsRelativeURI; 100 Endpoint = cfg.storage.s3.endpoint; 101 }; 102 AzureBlob = { 103 AccountName = cfg.storage.azureblob.accountName; 104 AccountKey = cfg.storage.azureblob.accountKey; 105 ContainerName = cfg.storage.azureblob.containerName; 106 }; 107 External = { 108 URL = cfg.storage.external.url; 109 }; 110 }; 111 Index = { 112 MySQL = { 113 Protocol = cfg.index.mysql.protocol; 114 Host = cfg.index.mysql.host; 115 Port = cfg.index.mysql.port; 116 User = cfg.index.mysql.user; 117 Password = cfg.index.mysql.password; 118 Database = cfg.index.mysql.database; 119 Params = { 120 parseTime = cfg.index.mysql.params.parseTime; 121 timeout = cfg.index.mysql.params.timeout; 122 }; 123 }; 124 Postgres = { 125 Host = cfg.index.postgres.host; 126 Port = cfg.index.postgres.port; 127 User = cfg.index.postgres.user; 128 Password = cfg.index.postgres.password; 129 Database = cfg.index.postgres.database; 130 Params = { 131 connect_timeout = cfg.index.postgres.params.connect_timeout; 132 sslmode = cfg.index.postgres.params.sslmode; 133 }; 134 }; 135 }; 136 }; 137 138 configFile = lib.pipe athensConfig [ 139 (lib.filterAttrsRecursive (_k: v: v != null)) 140 ((pkgs.formats.toml { }).generate "config.toml") 141 ]; 142in 143{ 144 meta = { 145 maintainers = pkgs.athens.meta.maintainers; 146 doc = ./athens.md; 147 }; 148 149 options.services.athens = { 150 enable = lib.mkEnableOption "Go module datastore and proxy"; 151 152 package = lib.mkOption { 153 default = pkgs.athens; 154 defaultText = lib.literalExpression "pkgs.athens"; 155 example = "pkgs.athens"; 156 description = "Which athens derivation to use"; 157 type = lib.types.package; 158 }; 159 160 goBinary = lib.mkOption { 161 type = lib.types.package; 162 default = pkgs.go; 163 defaultText = lib.literalExpression "pkgs.go"; 164 example = "pkgs.go_1_23"; 165 description = '' 166 The Go package used by Athens at runtime. 167 168 Athens primarily runs two Go commands: 169 1. `go mod download -json <module>@<version>` 170 2. `go list -m -json <module>@latest` 171 ''; 172 }; 173 174 goEnv = lib.mkOption { 175 type = lib.types.enum [ 176 "development" 177 "production" 178 ]; 179 description = "Specifies the type of environment to run. One of 'development' or 'production'."; 180 default = "development"; 181 example = "production"; 182 }; 183 184 goBinaryEnvVars = lib.mkOption { 185 type = lib.types.attrs; 186 description = "Environment variables to pass to the Go binary."; 187 example = '' 188 { "GOPROXY" = "direct", "GODEBUG" = "true" } 189 ''; 190 default = { }; 191 }; 192 193 goGetWorkers = lib.mkOption { 194 type = lib.types.int; 195 description = "Number of workers concurrently downloading modules."; 196 default = 10; 197 example = 32; 198 }; 199 200 goGetDir = lib.mkOption { 201 type = lib.types.nullOr lib.types.path; 202 description = '' 203 Temporary directory that Athens will use to 204 fetch modules from VCS prior to persisting 205 them to a storage backend. 206 207 If the value is empty, Athens will use the 208 default OS temp directory. 209 ''; 210 default = null; 211 example = "/tmp/athens"; 212 }; 213 214 protocolWorkers = lib.mkOption { 215 type = lib.types.int; 216 description = "Number of workers concurrently serving protocol paths."; 217 default = 30; 218 }; 219 220 logLevel = lib.mkOption { 221 type = lib.types.nullOr ( 222 lib.types.enum [ 223 "panic" 224 "fatal" 225 "error" 226 "warning" 227 "info" 228 "debug" 229 "trace" 230 ] 231 ); 232 description = '' 233 Log level for Athens. 234 Supports all logrus log levels (https://github.com/Sirupsen/logrus#level-logging)". 235 ''; 236 default = "warning"; 237 example = "debug"; 238 }; 239 240 cloudRuntime = lib.mkOption { 241 type = lib.types.enum [ 242 "GCP" 243 "none" 244 ]; 245 description = '' 246 Specifies the Cloud Provider on which the Proxy/registry is running. 247 ''; 248 default = "none"; 249 example = "GCP"; 250 }; 251 252 enablePprof = lib.mkOption { 253 type = lib.types.bool; 254 description = "Enable pprof endpoints."; 255 default = false; 256 }; 257 258 pprofPort = lib.mkOption { 259 type = lib.types.port; 260 description = "Port number for pprof endpoints."; 261 default = 3301; 262 example = 443; 263 }; 264 265 filterFile = lib.mkOption { 266 type = lib.types.nullOr lib.types.path; 267 description = "Filename for the include exclude filter."; 268 default = null; 269 example = lib.literalExpression '' 270 pkgs.writeText "filterFile" ''' 271 - github.com/azure 272 + github.com/azure/azure-sdk-for-go 273 D golang.org/x/tools 274 ''' 275 ''; 276 }; 277 278 robotsFile = lib.mkOption { 279 type = lib.types.nullOr lib.types.path; 280 description = "Provides /robots.txt for net crawlers."; 281 default = null; 282 example = lib.literalExpression ''pkgs.writeText "robots.txt" "# my custom robots.txt ..."''; 283 }; 284 285 timeout = lib.mkOption { 286 type = lib.types.int; 287 description = "Timeout for external network calls in seconds."; 288 default = 300; 289 example = 3; 290 }; 291 292 storageType = lib.mkOption { 293 type = lib.types.enum [ 294 "memory" 295 "disk" 296 "mongo" 297 "gcp" 298 "s3" 299 "azureblob" 300 "external" 301 ]; 302 description = "Specifies the type of storage backend to use."; 303 default = "disk"; 304 }; 305 306 tlsCertFile = lib.mkOption { 307 type = lib.types.nullOr lib.types.path; 308 description = "Path to the TLS certificate file."; 309 default = null; 310 example = "/etc/ssl/certs/athens.crt"; 311 }; 312 313 tlsKeyFile = lib.mkOption { 314 type = lib.types.nullOr lib.types.path; 315 description = "Path to the TLS key file."; 316 default = null; 317 example = "/etc/ssl/certs/athens.key"; 318 }; 319 320 port = lib.mkOption { 321 type = lib.types.port; 322 default = 3000; 323 description = '' 324 Port number Athens listens on. 325 ''; 326 example = 443; 327 }; 328 329 unixSocket = lib.mkOption { 330 type = lib.types.nullOr lib.types.path; 331 description = '' 332 Path to the unix socket file. 333 If set, Athens will listen on the unix socket instead of TCP socket. 334 ''; 335 default = null; 336 example = "/run/athens.sock"; 337 }; 338 339 globalEndpoint = lib.mkOption { 340 type = lib.types.str; 341 description = '' 342 Endpoint for a package registry in case of a proxy cache miss. 343 ''; 344 default = ""; 345 example = "http://upstream-athens.example.com:3000"; 346 }; 347 348 basicAuthUser = lib.mkOption { 349 type = lib.types.nullOr lib.types.str; 350 description = '' 351 Username for basic auth. 352 ''; 353 default = null; 354 example = "user"; 355 }; 356 357 basicAuthPass = lib.mkOption { 358 type = lib.types.nullOr lib.types.str; 359 description = '' 360 Password for basic auth. Warning: this is stored in plain text in the config file. 361 ''; 362 default = null; 363 example = "swordfish"; 364 }; 365 366 forceSSL = lib.mkOption { 367 type = lib.types.bool; 368 description = '' 369 Force SSL redirects for incoming requests. 370 ''; 371 default = false; 372 }; 373 374 validatorHook = lib.mkOption { 375 type = lib.types.nullOr lib.types.str; 376 description = '' 377 Endpoint to validate modules against. 378 379 Not used if empty. 380 ''; 381 default = null; 382 example = "https://validation.example.com"; 383 }; 384 385 pathPrefix = lib.mkOption { 386 type = lib.types.nullOr lib.types.str; 387 description = '' 388 Sets basepath for all routes. 389 ''; 390 default = null; 391 example = "/athens"; 392 }; 393 394 netrcPath = lib.mkOption { 395 type = lib.types.nullOr lib.types.path; 396 description = '' 397 Path to the .netrc file. 398 ''; 399 default = null; 400 example = "/home/user/.netrc"; 401 }; 402 403 githubToken = lib.mkOption { 404 type = lib.types.nullOr lib.types.str; 405 description = '' 406 Creates .netrc file with the given token to be used for GitHub. 407 Warning: this is stored in plain text in the config file. 408 ''; 409 default = null; 410 example = "ghp_1234567890"; 411 }; 412 413 hgrcPath = lib.mkOption { 414 type = lib.types.nullOr lib.types.path; 415 description = '' 416 Path to the .hgrc file. 417 ''; 418 default = null; 419 example = "/home/user/.hgrc"; 420 }; 421 422 traceExporter = lib.mkOption { 423 type = lib.types.nullOr ( 424 lib.types.enum [ 425 "jaeger" 426 "datadog" 427 ] 428 ); 429 description = '' 430 Trace exporter to use. 431 ''; 432 default = null; 433 }; 434 435 traceExporterURL = lib.mkOption { 436 type = lib.types.nullOr lib.types.str; 437 description = '' 438 URL endpoint that traces will be sent to. 439 ''; 440 default = null; 441 example = "http://localhost:14268"; 442 }; 443 444 statsExporter = lib.mkOption { 445 type = lib.types.nullOr (lib.types.enum [ "prometheus" ]); 446 description = "Stats exporter to use."; 447 default = null; 448 }; 449 450 sumDBs = lib.mkOption { 451 type = lib.types.listOf lib.types.str; 452 description = '' 453 List of fully qualified URLs that Athens will proxy 454 that the go command can use a checksum verifier. 455 ''; 456 default = [ "https://sum.golang.org" ]; 457 }; 458 459 noSumPatterns = lib.mkOption { 460 type = lib.types.listOf lib.types.str; 461 description = '' 462 List of patterns that Athens sum db proxy will return a 403 for. 463 ''; 464 default = [ ]; 465 example = [ "github.com/mycompany/*" ]; 466 }; 467 468 downloadMode = lib.mkOption { 469 type = lib.types.oneOf [ 470 (lib.types.enum [ 471 "sync" 472 "async" 473 "redirect" 474 "async_redirect" 475 "none" 476 ]) 477 (lib.types.strMatching "^file:.*$|^custom:.*$") 478 ]; 479 description = '' 480 Defines how Athens behaves when a module@version 481 is not found in storage. There are 7 options: 482 1. "sync": download the module synchronously and 483 return the results to the client. 484 2. "async": return 404, but asynchronously store the module 485 in the storage backend. 486 3. "redirect": return a 301 redirect status to the client 487 with the base URL as the DownloadRedirectURL from below. 488 4. "async_redirect": same as option number 3 but it will 489 asynchronously store the module to the backend. 490 5. "none": return 404 if a module is not found and do nothing. 491 6. "file:<path>": will point to an HCL file that specifies 492 any of the 5 options above based on different import paths. 493 7. "custom:<base64-encoded-hcl>" is the same as option 6 494 but the file is fully encoded in the option. This is 495 useful for using an environment variable in serverless 496 deployments. 497 ''; 498 default = "async_redirect"; 499 }; 500 501 networkMode = lib.mkOption { 502 type = lib.types.enum [ 503 "strict" 504 "offline" 505 "fallback" 506 ]; 507 description = '' 508 Configures how Athens will return the results 509 of the /list endpoint as it can be assembled from both its own 510 storage and the upstream VCS. 511 512 Note, that for better error messaging, this would also affect how other 513 endpoints behave. 514 515 Modes: 516 1. strict: merge VCS versions with storage versions, but fail if either of them fails. 517 2. offline: only get storage versions, never reach out to VCS. 518 3. fallback: only return storage versions, if VCS fails. Note this means that you may 519 see inconsistent results since fallback mode does a best effort of giving you what's 520 available at the time of requesting versions. 521 ''; 522 default = "strict"; 523 }; 524 525 downloadURL = lib.mkOption { 526 type = lib.types.str; 527 description = "URL used if DownloadMode is set to redirect."; 528 default = "https://proxy.golang.org"; 529 }; 530 531 singleFlightType = lib.mkOption { 532 type = lib.types.enum [ 533 "memory" 534 "etcd" 535 "redis" 536 "redis-sentinel" 537 "gcp" 538 "azureblob" 539 ]; 540 description = '' 541 Determines what mechanism Athens uses to manage concurrency flowing into the Athens backend. 542 ''; 543 default = "memory"; 544 }; 545 546 indexType = lib.mkOption { 547 type = lib.types.enum [ 548 "none" 549 "memory" 550 "mysql" 551 "postgres" 552 ]; 553 description = '' 554 Type of index backend Athens will use. 555 ''; 556 default = "none"; 557 }; 558 559 shutdownTimeout = lib.mkOption { 560 type = lib.types.int; 561 description = '' 562 Number of seconds to wait for the server to shutdown gracefully. 563 ''; 564 default = 60; 565 example = 1; 566 }; 567 568 singleFlight = { 569 etcd = { 570 endpoints = lib.mkOption { 571 type = lib.types.listOf lib.types.str; 572 description = "URLs that determine all distributed etcd servers."; 573 default = [ ]; 574 example = [ "localhost:2379" ]; 575 }; 576 }; 577 redis = { 578 endpoint = lib.mkOption { 579 type = lib.types.str; 580 description = "URL of the redis server."; 581 default = ""; 582 example = "localhost:6379"; 583 }; 584 password = lib.mkOption { 585 type = lib.types.str; 586 description = "Password for the redis server. Warning: this is stored in plain text in the config file."; 587 default = ""; 588 example = "swordfish"; 589 }; 590 591 lockConfig = { 592 ttl = lib.mkOption { 593 type = lib.types.int; 594 description = "TTL for the lock in seconds."; 595 default = 900; 596 example = 1; 597 }; 598 timeout = lib.mkOption { 599 type = lib.types.int; 600 description = "Timeout for the lock in seconds."; 601 default = 15; 602 example = 1; 603 }; 604 maxRetries = lib.mkOption { 605 type = lib.types.int; 606 description = "Maximum number of retries for the lock."; 607 default = 10; 608 example = 1; 609 }; 610 }; 611 }; 612 613 redisSentinel = { 614 endpoints = lib.mkOption { 615 type = lib.types.listOf lib.types.str; 616 description = "URLs that determine all distributed redis servers."; 617 default = [ ]; 618 example = [ "localhost:26379" ]; 619 }; 620 masterName = lib.mkOption { 621 type = lib.types.str; 622 description = "Name of the sentinel master server."; 623 default = ""; 624 example = "redis-1"; 625 }; 626 sentinelPassword = lib.mkOption { 627 type = lib.types.str; 628 description = "Password for the sentinel server. Warning: this is stored in plain text in the config file."; 629 default = ""; 630 example = "swordfish"; 631 }; 632 633 lockConfig = { 634 ttl = lib.mkOption { 635 type = lib.types.int; 636 description = "TTL for the lock in seconds."; 637 default = 900; 638 example = 1; 639 }; 640 timeout = lib.mkOption { 641 type = lib.types.int; 642 description = "Timeout for the lock in seconds."; 643 default = 15; 644 example = 1; 645 }; 646 maxRetries = lib.mkOption { 647 type = lib.types.int; 648 description = "Maximum number of retries for the lock."; 649 default = 10; 650 example = 1; 651 }; 652 }; 653 }; 654 }; 655 656 storage = { 657 cdn = { 658 endpoint = lib.mkOption { 659 type = lib.types.nullOr lib.types.str; 660 description = "hostname of the CDN server."; 661 example = "cdn.example.com"; 662 default = null; 663 }; 664 }; 665 666 disk = { 667 rootPath = lib.mkOption { 668 type = lib.types.nullOr lib.types.path; 669 description = "Athens disk root folder."; 670 default = "/var/lib/athens"; 671 }; 672 }; 673 674 gcp = { 675 projectID = lib.mkOption { 676 type = lib.types.nullOr lib.types.str; 677 description = "GCP project ID."; 678 example = "my-project"; 679 default = null; 680 }; 681 bucket = lib.mkOption { 682 type = lib.types.nullOr lib.types.str; 683 description = "GCP backend storage bucket."; 684 example = "my-bucket"; 685 default = null; 686 }; 687 jsonKey = lib.mkOption { 688 type = lib.types.nullOr lib.types.str; 689 description = "Base64 encoded GCP service account key. Warning: this is stored in plain text in the config file."; 690 default = null; 691 }; 692 }; 693 694 mongo = { 695 url = lib.mkOption { 696 type = lib.types.nullOr lib.types.str; 697 description = "URL of the mongo database."; 698 example = "mongodb://localhost:27017"; 699 default = null; 700 }; 701 defaultDBName = lib.mkOption { 702 type = lib.types.nullOr lib.types.str; 703 description = "Name of the mongo database."; 704 example = "athens"; 705 default = null; 706 }; 707 certPath = lib.mkOption { 708 type = lib.types.nullOr lib.types.path; 709 description = "Path to the certificate file for the mongo database."; 710 example = "/etc/ssl/mongo.pem"; 711 default = null; 712 }; 713 insecure = lib.mkOption { 714 type = lib.types.bool; 715 description = "Allow insecure connections to the mongo database."; 716 default = false; 717 }; 718 }; 719 720 s3 = { 721 region = lib.mkOption { 722 type = lib.types.nullOr lib.types.str; 723 description = "Region of the S3 storage backend."; 724 example = "eu-west-3"; 725 default = null; 726 }; 727 key = lib.mkOption { 728 type = lib.types.nullOr lib.types.str; 729 description = "Access key id for the S3 storage backend."; 730 default = null; 731 }; 732 secret = lib.mkOption { 733 type = lib.types.str; 734 description = "Secret key for the S3 storage backend. Warning: this is stored in plain text in the config file."; 735 default = ""; 736 }; 737 token = lib.mkOption { 738 type = lib.types.nullOr lib.types.str; 739 description = "Token for the S3 storage backend. Warning: this is stored in plain text in the config file."; 740 default = null; 741 }; 742 bucket = lib.mkOption { 743 type = lib.types.nullOr lib.types.str; 744 description = "Bucket name for the S3 storage backend."; 745 example = "gomods"; 746 default = null; 747 }; 748 forcePathStyle = lib.mkOption { 749 type = lib.types.bool; 750 description = "Force path style for the S3 storage backend."; 751 default = false; 752 }; 753 useDefaultConfiguration = lib.mkOption { 754 type = lib.types.bool; 755 description = "Use default configuration for the S3 storage backend."; 756 default = false; 757 }; 758 credentialsEndpoint = lib.mkOption { 759 type = lib.types.str; 760 description = "Credentials endpoint for the S3 storage backend."; 761 default = ""; 762 }; 763 awsContainerCredentialsRelativeURI = lib.mkOption { 764 type = lib.types.nullOr lib.types.str; 765 description = "Container relative url (used by fargate)."; 766 default = null; 767 }; 768 endpoint = lib.mkOption { 769 type = lib.types.nullOr lib.types.str; 770 description = "Endpoint for the S3 storage backend."; 771 default = null; 772 }; 773 }; 774 775 azureblob = { 776 accountName = lib.mkOption { 777 type = lib.types.nullOr lib.types.str; 778 description = "Account name for the Azure Blob storage backend."; 779 default = null; 780 }; 781 accountKey = lib.mkOption { 782 type = lib.types.nullOr lib.types.str; 783 description = "Account key for the Azure Blob storage backend. Warning: this is stored in plain text in the config file."; 784 default = null; 785 }; 786 containerName = lib.mkOption { 787 type = lib.types.nullOr lib.types.str; 788 description = "Container name for the Azure Blob storage backend."; 789 default = null; 790 }; 791 }; 792 793 external = { 794 url = lib.mkOption { 795 type = lib.types.nullOr lib.types.str; 796 description = "URL of the backend storage layer."; 797 example = "https://athens.example.com"; 798 default = null; 799 }; 800 }; 801 }; 802 803 index = { 804 mysql = { 805 protocol = lib.mkOption { 806 type = lib.types.str; 807 description = "Protocol for the MySQL database."; 808 default = "tcp"; 809 }; 810 host = lib.mkOption { 811 type = lib.types.str; 812 description = "Host for the MySQL database."; 813 default = "localhost"; 814 }; 815 port = lib.mkOption { 816 type = lib.types.port; 817 description = "Port for the MySQL database."; 818 default = 3306; 819 }; 820 user = lib.mkOption { 821 type = lib.types.str; 822 description = "User for the MySQL database."; 823 default = "root"; 824 }; 825 password = lib.mkOption { 826 type = lib.types.nullOr lib.types.str; 827 description = "Password for the MySQL database. Warning: this is stored in plain text in the config file."; 828 default = null; 829 }; 830 database = lib.mkOption { 831 type = lib.types.str; 832 description = "Database name for the MySQL database."; 833 default = "athens"; 834 }; 835 params = { 836 parseTime = lib.mkOption { 837 type = lib.types.nullOr lib.types.str; 838 description = "Parse time for the MySQL database."; 839 default = "true"; 840 }; 841 timeout = lib.mkOption { 842 type = lib.types.nullOr lib.types.str; 843 description = "Timeout for the MySQL database."; 844 default = "30s"; 845 }; 846 }; 847 }; 848 849 postgres = { 850 host = lib.mkOption { 851 type = lib.types.str; 852 description = "Host for the Postgres database."; 853 default = "localhost"; 854 }; 855 port = lib.mkOption { 856 type = lib.types.port; 857 description = "Port for the Postgres database."; 858 default = 5432; 859 }; 860 user = lib.mkOption { 861 type = lib.types.str; 862 description = "User for the Postgres database."; 863 default = "postgres"; 864 }; 865 password = lib.mkOption { 866 type = lib.types.nullOr lib.types.str; 867 description = "Password for the Postgres database. Warning: this is stored in plain text in the config file."; 868 default = null; 869 }; 870 database = lib.mkOption { 871 type = lib.types.str; 872 description = "Database name for the Postgres database."; 873 default = "athens"; 874 }; 875 params = { 876 connect_timeout = lib.mkOption { 877 type = lib.types.nullOr lib.types.str; 878 description = "Connect timeout for the Postgres database."; 879 default = "30s"; 880 }; 881 sslmode = lib.mkOption { 882 type = lib.types.nullOr lib.types.str; 883 description = "SSL mode for the Postgres database."; 884 default = "disable"; 885 }; 886 }; 887 }; 888 }; 889 890 extraConfig = lib.mkOption { 891 type = lib.types.attrs; 892 description = '' 893 Extra configuration options for the athens config file. 894 ''; 895 default = { }; 896 }; 897 }; 898 899 config = lib.mkIf cfg.enable { 900 systemd.services.athens = { 901 description = "Athens Go module proxy"; 902 documentation = [ "https://docs.gomods.io" ]; 903 904 wantedBy = [ "multi-user.target" ]; 905 after = [ "network-online.target" ]; 906 wants = [ "network-online.target" ]; 907 908 serviceConfig = { 909 Restart = "on-abnormal"; 910 Nice = 5; 911 ExecStart = "${cfg.package}/bin/athens -config_file=${configFile}"; 912 913 KillMode = "mixed"; 914 KillSignal = "SIGINT"; 915 TimeoutStopSec = cfg.shutdownTimeout; 916 917 LimitNOFILE = 1048576; 918 LimitNPROC = 512; 919 920 DynamicUser = true; 921 PrivateTmp = true; 922 PrivateDevices = true; 923 ProtectHome = "read-only"; 924 ProtectSystem = "full"; 925 926 ReadWritePaths = lib.mkIf ( 927 cfg.storage.disk.rootPath != null && (!lib.hasPrefix "/var/lib/" cfg.storage.disk.rootPath) 928 ) [ cfg.storage.disk.rootPath ]; 929 StateDirectory = lib.mkIf (lib.hasPrefix "/var/lib/" cfg.storage.disk.rootPath) [ 930 (lib.removePrefix "/var/lib/" cfg.storage.disk.rootPath) 931 ]; 932 933 CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; 934 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 935 NoNewPrivileges = true; 936 }; 937 }; 938 939 networking.firewall = { 940 allowedTCPPorts = 941 lib.optionals (cfg.unixSocket == null) [ cfg.port ] 942 ++ lib.optionals cfg.enablePprof [ cfg.pprofPort ]; 943 }; 944 }; 945 946 imports = [ 947 (lib.mkRemovedOptionModule [ 948 "services" 949 "athens" 950 "storage" 951 "minio" 952 ] "Support for Minio storage backend has been removed, as minio is unmaintained.") 953 ]; 954}