fixture.nix (37017B)
1 { 2 lib, 3 nixosSystem, 4 pkgs, 5 service, 6 toolchain, 7 }: 8 let 9 nativeInputs = service.mkNativeInputs { 10 nativeBuildInputs = [ pkgs.coreutils ]; 11 environment = { 12 RADROOTS_SERVICE_FIXTURE = { 13 classification = "nonsecret"; 14 value = "1"; 15 }; 16 }; 17 }; 18 fixtureSource = ./fixture-service; 19 package = service.mkServicePackage { 20 inherit nativeInputs toolchain; 21 source = fixtureSource; 22 cargoLock = fixtureSource + "/Cargo.lock"; 23 servicePackage = "fixture-service"; 24 binaryName = "fixture-service"; 25 releaseProfile = "release"; 26 }; 27 apps = service.mkServiceApps { 28 serviceName = "fixture_service"; 29 inherit nativeInputs package toolchain; 30 binaryName = "fixture-service"; 31 releaseAcceptanceCommand = '' 32 output="$(fixture-service --help)" 33 if [ "$output" != "fixture-service" ]; then 34 echo "fixture release acceptance observed unexpected output" >&2 35 exit 1 36 fi 37 printf '%s\n' "fixture-service release acceptance" 38 ''; 39 }; 40 devShell = service.mkServiceDevShell { 41 serviceName = "fixture_service"; 42 inherit nativeInputs toolchain; 43 }; 44 fixtureBuildInfo = { 45 serviceVersion = "0.1.0-alpha"; 46 serviceCommit = "1111111111111111111111111111111111111111"; 47 libRevision = "2222222222222222222222222222222222222222"; 48 rustVersion = "1.97.1"; 49 target = pkgs.stdenv.hostPlatform.rust.rustcTarget; 50 featureProfile = "service-host"; 51 contractVersions = { 52 config = 1; 53 state = 2; 54 admin = 3; 55 status = 4; 56 provider = 5; 57 }; 58 }; 59 ociImage = 60 if pkgs.stdenv.isLinux then 61 service.mkServiceOciImage { 62 serviceName = "fixture_service"; 63 inherit package; 64 binaryName = "fixture-service"; 65 buildInfo = fixtureBuildInfo; 66 } 67 else 68 null; 69 ociImageCheck = 70 if pkgs.stdenv.isLinux then 71 pkgs.runCommand "fixture-service-oci-image" 72 { 73 nativeBuildInputs = [ 74 pkgs.coreutils 75 pkgs.gnutar 76 pkgs.gzip 77 pkgs.jq 78 ]; 79 } 80 '' 81 mkdir image 82 tar -xzf ${ociImage} -C image 83 config_file="$(jq -er '.[0].Config' image/manifest.json)" 84 test -f "image/$config_file" 85 86 jq -e ' 87 .architecture == "${if pkgs.stdenv.hostPlatform.isAarch64 then "arm64" else "amd64"}" and 88 .os == "linux" and 89 .created == "1970-01-01T00:00:01+00:00" and 90 .config.User == "65532:65532" and 91 .config.Entrypoint == ["${package}/bin/fixture-service"] and 92 .config.WorkingDir == "/" and 93 .config.Env == ["SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"] and 94 .config.StopSignal == "SIGTERM" and 95 (.config | has("Volumes") | not) and 96 .config.Labels == { 97 "dev.radroots.build.feature-profile": "service-host", 98 "dev.radroots.build.lib-revision": "2222222222222222222222222222222222222222", 99 "dev.radroots.build.rust-version": "1.97.1", 100 "dev.radroots.build.target": "${pkgs.stdenv.hostPlatform.rust.rustcTarget}", 101 "dev.radroots.contract.admin-version": "3", 102 "dev.radroots.contract.config-version": "1", 103 "dev.radroots.contract.provider-version": "5", 104 "dev.radroots.contract.state-version": "2", 105 "dev.radroots.contract.status-version": "4", 106 "dev.radroots.mount.config": "/etc/radroots/services/fixture_service", 107 "dev.radroots.mount.config.mode": "read-only", 108 "dev.radroots.mount.credentials": "/etc/radroots/secrets/services/fixture_service", 109 "dev.radroots.mount.credentials.mode": "read-only", 110 "dev.radroots.mount.runtime": "/run/radroots/services/fixture_service", 111 "dev.radroots.mount.runtime.mode": "read-write", 112 "dev.radroots.mount.state": "/var/lib/radroots/services/fixture_service", 113 "dev.radroots.mount.state.mode": "read-write", 114 "dev.radroots.rootfs": "read-only-compatible", 115 "org.opencontainers.image.description": "Hardened fixture_service service image", 116 "org.opencontainers.image.licenses": "AGPL-3.0-or-later", 117 "org.opencontainers.image.revision": "1111111111111111111111111111111111111111", 118 "org.opencontainers.image.title": "fixture_service", 119 "org.opencontainers.image.version": "0.1.0-alpha" 120 } 121 ' "image/$config_file" 122 123 jq -e '.[0].RepoTags == ["fixture-service:0.1.0-alpha"]' image/manifest.json 124 jq -e '([.[0].Layers | length] | .[0] >= 1 and .[0] <= 2)' image/manifest.json 125 jq -er '.[0].Layers[]' image/manifest.json | while IFS= read -r layer; do 126 tar -tf "image/$layer" 127 done | sort -u > image-entries 128 129 grep -E '/bin/fixture-service$' image-entries 130 if grep -E '(^|/)(bin/(ba)?sh|bin/nix|bin/cargo|bin/rustc|Cargo.toml|src/)' image-entries; then 131 echo "fixture OCI image contains a development or shell payload" >&2 132 exit 1 133 fi 134 135 touch "$out" 136 '' 137 else 138 null; 139 nixosModule = service.mkServiceNixosModule { 140 serviceName = "fixture_service"; 141 binaryName = "fixture-service"; 142 packageFor = _: package; 143 commandForInstance = instanceName: [ 144 "--instance" 145 instanceName 146 "--config" 147 "/etc/radroots/services/fixture_service/${instanceName}/config.toml" 148 ]; 149 }; 150 nixosConfiguration = 151 if pkgs.stdenv.isLinux then 152 nixosSystem { 153 system = pkgs.stdenv.hostPlatform.system; 154 modules = [ 155 nixosModule 156 { 157 system.stateVersion = "25.11"; 158 users.groups.fixture-admin = { }; 159 services.radroots.fixture_service = { 160 enable = true; 161 adminGroup = "fixture-admin"; 162 instances.primary = { 163 configurationFile = pkgs.writeText "fixture-service-config.toml" '' 164 contract_version = 1 165 ''; 166 credentials.api-token = "/run/operator/fixture-api-token"; 167 }; 168 }; 169 } 170 ]; 171 } 172 else 173 null; 174 nixosUnitName = "radroots-fixture_service-primary"; 175 nixosService = 176 if pkgs.stdenv.isLinux then nixosConfiguration.config.systemd.services.${nixosUnitName} else null; 177 nixosUnitText = 178 if pkgs.stdenv.isLinux then 179 nixosConfiguration.config.system.build.units."${nixosUnitName}.service".text 180 else 181 null; 182 nixosModuleCheck = 183 if pkgs.stdenv.isLinux then 184 pkgs.runCommand "fixture-service-nixos-module" 185 { 186 nativeBuildInputs = [ 187 pkgs.gnugrep 188 ]; 189 unit = pkgs.writeText "${nixosUnitName}.service" nixosUnitText; 190 } 191 '' 192 grep -Fx 'Type=simple' "$unit" 193 grep -Fx 'DynamicUser=true' "$unit" 194 grep -Fx 'User=radroots-fixture_service' "$unit" 195 grep -Fx 'Group=fixture-admin' "$unit" 196 grep -Fx 'UMask=0077' "$unit" 197 grep -Fx 'ConfigurationDirectory=radroots/services/fixture_service/primary' "$unit" 198 grep -Fx 'ConfigurationDirectoryMode=0500' "$unit" 199 grep -Fx 'StateDirectory=radroots/services/fixture_service/primary' "$unit" 200 grep -Fx 'StateDirectoryMode=0700' "$unit" 201 grep -Fx 'CacheDirectory=radroots/services/fixture_service/primary' "$unit" 202 grep -Fx 'CacheDirectoryMode=0700' "$unit" 203 grep -Fx 'RuntimeDirectory=radroots/services/fixture_service/primary' "$unit" 204 grep -Fx 'RuntimeDirectoryMode=0750' "$unit" 205 grep -Fx 'LoadCredential=api-token:/run/operator/fixture-api-token' "$unit" 206 grep -Fx 'NoNewPrivileges=true' "$unit" 207 grep -Fx 'PrivateTmp=true' "$unit" 208 grep -Fx 'PrivateDevices=true' "$unit" 209 grep -Fx 'ProtectSystem=strict' "$unit" 210 grep -Fx 'ProtectHome=true' "$unit" 211 grep -Fx 'ProtectKernelTunables=true' "$unit" 212 grep -Fx 'ProtectKernelModules=true' "$unit" 213 grep -Fx 'ProtectKernelLogs=true' "$unit" 214 grep -Fx 'ProtectControlGroups=true' "$unit" 215 grep -Fx 'ProtectHostname=true' "$unit" 216 grep -Fx 'ProtectClock=true' "$unit" 217 grep -Fx 'RestrictSUIDSGID=true' "$unit" 218 grep -Fx 'LockPersonality=true' "$unit" 219 grep -Fx 'CapabilityBoundingSet=' "$unit" 220 grep -Fx 'AmbientCapabilities=' "$unit" 221 test "$(grep -c '^RestrictAddressFamilies=' "$unit")" = 3 222 grep -Fx 'RestrictAddressFamilies=AF_UNIX' "$unit" 223 grep -Fx 'RestrictAddressFamilies=AF_INET' "$unit" 224 grep -Fx 'RestrictAddressFamilies=AF_INET6' "$unit" 225 grep -Fx 'RestrictNamespaces=true' "$unit" 226 grep -Fx 'RestrictRealtime=true' "$unit" 227 grep -Fx 'RemoveIPC=true' "$unit" 228 grep -Fx 'DevicePolicy=closed' "$unit" 229 grep -Fx 'KeyringMode=private' "$unit" 230 grep -Fx 'ProcSubset=pid' "$unit" 231 grep -Fx 'ProtectProc=invisible' "$unit" 232 grep -Fx 'SystemCallArchitectures=native' "$unit" 233 grep -Fx 'TimeoutStopSec=30s' "$unit" 234 grep -Fx 'KillSignal=SIGTERM' "$unit" 235 grep -Fx 'KillMode=control-group' "$unit" 236 grep -Fx 'Restart=on-failure' "$unit" 237 grep -Fx 'RestartSec=5s' "$unit" 238 if grep -E '^(MemoryDenyWriteExecute|SystemCallFilter)=' "$unit"; then 239 echo "fixture unit enabled an unqualified hardening control" >&2 240 exit 1 241 fi 242 if grep -E '^Environment=.*(api-token|fixture-api-token)' "$unit"; then 243 echo "fixture unit exposed credential material through its environment" >&2 244 exit 1 245 fi 246 touch "$out" 247 '' 248 else 249 null; 250 appSmoke = pkgs.runCommand "fixture-service-app-smoke" { } '' 251 test "$(${apps.default.program} --help)" = "fixture-service" 252 test "$(${apps.release-acceptance.program})" = "fixture-service release acceptance" 253 touch "$out" 254 ''; 255 hooks = { 256 sqlx = pkgs.runCommand "fixture-service-sqlx" { } '' 257 if grep -F "sqlx" ${fixtureSource}/Cargo.toml; then 258 echo "fixture unexpectedly acquired a SQLx dependency" >&2 259 exit 1 260 fi 261 touch "$out" 262 ''; 263 config = pkgs.runCommand "fixture-service-config" { } '' 264 grep -Fx 'publish = false' ${fixtureSource}/Cargo.toml 265 touch "$out" 266 ''; 267 source-lock = pkgs.runCommand "fixture-service-source-lock" { } '' 268 grep -Fx 'version = 4' ${fixtureSource}/Cargo.lock 269 touch "$out" 270 ''; 271 integration = pkgs.runCommand "fixture-service-integration" { nativeBuildInputs = [ package ]; } '' 272 fixture-service --help | grep -Fx "fixture-service" 273 touch "$out" 274 ''; 275 }; 276 smoke = 277 pkgs.runCommand "radroots-service-helper-fixture-smoke" 278 { 279 nativeBuildInputs = [ 280 package 281 pkgs.file 282 pkgs.gnugrep 283 pkgs.nix 284 ]; 285 } 286 '' 287 fixture-service --help > output 288 grep -Fx "fixture-service" output 289 file ${package}/bin/fixture-service > file-type 290 if grep -Fi "script" file-type; then 291 echo "fixture package installed a source wrapper" >&2 292 exit 1 293 fi 294 test ! -e ${package}/Cargo.toml 295 test ! -e ${package}/src 296 if nix-store --query --requisites ${package} | grep -Fx ${toolchain}; then 297 echo "fixture runtime closure retains the Rust toolchain" >&2 298 exit 1 299 fi 300 touch "$out" 301 ''; 302 checks = service.mkServiceChecks { 303 serviceName = "fixture_service"; 304 inherit 305 hooks 306 nativeInputs 307 package 308 toolchain 309 ; 310 source = fixtureSource; 311 cargoLock = fixtureSource + "/Cargo.lock"; 312 extraChecks = { 313 app-smoke = appSmoke; 314 inherit smoke; 315 } 316 // lib.optionalAttrs pkgs.stdenv.isLinux { 317 nixos-module = nixosModuleCheck; 318 oci-image = ociImageCheck; 319 }; 320 }; 321 outputs = service.mkServiceOutputs { 322 serviceName = "fixture_service"; 323 inherit nativeInputs package; 324 inherit apps checks; 325 devShells.default = devShell; 326 extraPackages = lib.optionalAttrs pkgs.stdenv.isLinux { 327 oci = ociImage; 328 }; 329 }; 330 invalidName = builtins.tryEval ( 331 (service.mkServiceOutputs { 332 serviceName = "../fixture"; 333 inherit nativeInputs package; 334 }).packages.default.outPath 335 ); 336 defaultOverride = builtins.tryEval ( 337 (service.mkServiceOutputs { 338 serviceName = "fixture_service"; 339 inherit nativeInputs package; 340 extraPackages.default = package; 341 }).packages.default.outPath 342 ); 343 invalidPackage = builtins.tryEval ( 344 (service.mkServiceOutputs { 345 serviceName = "fixture_service"; 346 inherit nativeInputs; 347 package = "not-a-derivation"; 348 }).packages.default 349 ); 350 invalidNativeInputs = builtins.tryEval ( 351 (service.mkServiceOutputs { 352 serviceName = "fixture_service"; 353 inherit package; 354 nativeInputs = { }; 355 }).nativeInputs 356 ); 357 invalidNativeInputDefinitions = 358 map 359 ( 360 environment: 361 builtins.tryEval (builtins.deepSeq (service.mkNativeInputs { inherit environment; }) true) 362 ) 363 [ 364 { 365 LEGACY_VALUE = "untyped"; 366 } 367 { 368 CLASSIFIED_SECRET = { 369 classification = "secret"; 370 value = "redacted"; 371 }; 372 } 373 { 374 EXTRA_FIELD = { 375 classification = "nonsecret"; 376 value = "value"; 377 unexpected = true; 378 }; 379 } 380 { 381 API_TOKEN = { 382 classification = "nonsecret"; 383 value = "redacted"; 384 }; 385 } 386 { 387 OVERLONG_VALUE = { 388 classification = "nonsecret"; 389 value = lib.concatStrings (lib.replicate 4097 "a"); 390 }; 391 } 392 ]; 393 invalidServicePackage = builtins.tryEval ( 394 (service.mkServicePackage { 395 inherit nativeInputs toolchain; 396 source = fixtureSource; 397 cargoLock = fixtureSource + "/Cargo.lock"; 398 servicePackage = "../fixture"; 399 }).outPath 400 ); 401 invalidBinaryName = builtins.tryEval ( 402 (service.mkServicePackage { 403 inherit nativeInputs toolchain; 404 source = fixtureSource; 405 cargoLock = fixtureSource + "/Cargo.lock"; 406 servicePackage = "fixture-service"; 407 binaryName = "fixture service"; 408 }).outPath 409 ); 410 invalidReleaseProfile = builtins.tryEval ( 411 (service.mkServicePackage { 412 inherit nativeInputs toolchain; 413 source = fixtureSource; 414 cargoLock = fixtureSource + "/Cargo.lock"; 415 servicePackage = "fixture-service"; 416 releaseProfile = "dev"; 417 }).outPath 418 ); 419 profileOverride = builtins.tryEval ( 420 (service.mkServicePackage { 421 inherit toolchain; 422 source = fixtureSource; 423 cargoLock = fixtureSource + "/Cargo.lock"; 424 servicePackage = "fixture-service"; 425 nativeInputs = service.mkNativeInputs { 426 environment.CARGO_PROFILE = { 427 classification = "nonsecret"; 428 value = "dev"; 429 }; 430 }; 431 }).outPath 432 ); 433 checkArgs = { 434 serviceName = "fixture_service"; 435 inherit 436 hooks 437 nativeInputs 438 package 439 toolchain 440 ; 441 source = fixtureSource; 442 cargoLock = fixtureSource + "/Cargo.lock"; 443 }; 444 invalidHookResults = map ( 445 hookName: 446 builtins.tryEval ( 447 (service.mkServiceChecks ( 448 checkArgs 449 // { 450 hooks = hooks // { 451 ${hookName} = "not-a-derivation"; 452 }; 453 } 454 )).check.outPath 455 ) 456 ) (builtins.attrNames hooks); 457 missingHook = builtins.tryEval ( 458 (service.mkServiceChecks ( 459 checkArgs 460 // { 461 hooks = builtins.removeAttrs hooks [ "sqlx" ]; 462 } 463 )).check.outPath 464 ); 465 unexpectedHook = builtins.tryEval ( 466 (service.mkServiceChecks ( 467 checkArgs 468 // { 469 hooks = hooks // { 470 other = smoke; 471 }; 472 } 473 )).check.outPath 474 ); 475 weakenedPolicyResults = 476 map 477 ( 478 variable: 479 builtins.tryEval ( 480 (service.mkServiceChecks ( 481 checkArgs 482 // { 483 nativeInputs = service.mkNativeInputs { 484 environment.${variable} = { 485 classification = "nonsecret"; 486 value = "override"; 487 }; 488 }; 489 } 490 )).check.outPath 491 ) 492 ) 493 [ 494 "CARGO_PROFILE" 495 "RUSTDOCFLAGS" 496 "RUSTFLAGS" 497 ]; 498 invalidExtraCheck = builtins.tryEval ( 499 (service.mkServiceChecks ( 500 checkArgs 501 // { 502 extraChecks.other = "not-a-derivation"; 503 } 504 )).check.outPath 505 ); 506 standardOverride = builtins.tryEval ( 507 (service.mkServiceChecks ( 508 checkArgs 509 // { 510 extraChecks.test = smoke; 511 } 512 )).check.outPath 513 ); 514 appArgs = { 515 serviceName = "fixture_service"; 516 inherit nativeInputs package toolchain; 517 binaryName = "fixture-service"; 518 releaseAcceptanceCommand = "fixture-service --help"; 519 }; 520 invalidAppResults = [ 521 (builtins.tryEval ( 522 (service.mkServiceApps (appArgs // { serviceName = "../fixture"; })).default.program 523 )) 524 (builtins.tryEval ( 525 (service.mkServiceApps (appArgs // { package = "not-a-derivation"; })).default.program 526 )) 527 (builtins.tryEval ( 528 (service.mkServiceApps (appArgs // { binaryName = "fixture service"; })).default.program 529 )) 530 (builtins.tryEval ( 531 (service.mkServiceApps (appArgs // { toolchain = "not-a-derivation"; })).default.program 532 )) 533 (builtins.tryEval ((service.mkServiceApps (appArgs // { nativeInputs = { }; })).default.program)) 534 (builtins.tryEval ( 535 (service.mkServiceApps ( 536 appArgs 537 // { 538 nativeInputs = service.mkNativeInputs { nativeBuildInputs = [ "not-a-derivation" ]; }; 539 } 540 )).default.program 541 )) 542 (builtins.tryEval ( 543 (service.mkServiceApps ( 544 appArgs 545 // { 546 nativeInputs = service.mkNativeInputs { environment.VALUE = 1; }; 547 } 548 )).default.program 549 )) 550 (builtins.tryEval ( 551 (service.mkServiceApps ( 552 appArgs 553 // { 554 nativeInputs = service.mkNativeInputs { 555 environment."INVALID-NAME" = { 556 classification = "nonsecret"; 557 value = "value"; 558 }; 559 }; 560 } 561 )).default.program 562 )) 563 (builtins.tryEval ( 564 (service.mkServiceApps ( 565 appArgs 566 // { 567 nativeInputs = service.mkNativeInputs { 568 environment.PATH = { 569 classification = "nonsecret"; 570 value = "/tmp"; 571 }; 572 }; 573 } 574 )).default.program 575 )) 576 (builtins.tryEval ( 577 (service.mkServiceApps (appArgs // { releaseAcceptanceCommand = ""; })).default.program 578 )) 579 ]; 580 devShellArgs = { 581 serviceName = "fixture_service"; 582 inherit nativeInputs toolchain; 583 }; 584 invalidDevShellResults = [ 585 (builtins.tryEval ( 586 (service.mkServiceDevShell (devShellArgs // { serviceName = "../fixture"; })).drvPath 587 )) 588 (builtins.tryEval ( 589 (service.mkServiceDevShell (devShellArgs // { toolchain = "not-a-derivation"; })).drvPath 590 )) 591 (builtins.tryEval ((service.mkServiceDevShell (devShellArgs // { nativeInputs = { }; })).drvPath)) 592 (builtins.tryEval ( 593 (service.mkServiceDevShell ( 594 devShellArgs 595 // { 596 nativeInputs = service.mkNativeInputs { buildInputs = [ "not-a-derivation" ]; }; 597 } 598 )).drvPath 599 )) 600 (builtins.tryEval ( 601 (service.mkServiceDevShell ( 602 devShellArgs 603 // { 604 nativeInputs = service.mkNativeInputs { environment.VALUE = 1; }; 605 } 606 )).drvPath 607 )) 608 (builtins.tryEval ( 609 (service.mkServiceDevShell ( 610 devShellArgs 611 // { 612 nativeInputs = service.mkNativeInputs { 613 environment."INVALID-NAME" = { 614 classification = "nonsecret"; 615 value = "value"; 616 }; 617 }; 618 } 619 )).drvPath 620 )) 621 (builtins.tryEval ( 622 (service.mkServiceDevShell ( 623 devShellArgs 624 // { 625 nativeInputs = service.mkNativeInputs { 626 environment.RUSTC = { 627 classification = "nonsecret"; 628 value = "/tmp/rustc"; 629 }; 630 }; 631 } 632 )).drvPath 633 )) 634 ]; 635 ociArgs = { 636 serviceName = "fixture_service"; 637 inherit package; 638 binaryName = "fixture-service"; 639 buildInfo = fixtureBuildInfo; 640 }; 641 maximumOciResult = 642 if pkgs.stdenv.isLinux then 643 builtins.tryEval ( 644 (service.mkServiceOciImage ( 645 ociArgs 646 // { 647 serviceName = lib.concatStrings (lib.replicate 128 "a"); 648 buildInfo = fixtureBuildInfo // { 649 serviceVersion = lib.concatStrings (lib.replicate 128 "1"); 650 contractVersions = lib.mapAttrs (_: _: 4294967295) fixtureBuildInfo.contractVersions; 651 }; 652 } 653 )).outPath 654 ) 655 else 656 { 657 success = true; 658 value = null; 659 }; 660 invalidOciResults = lib.optionals pkgs.stdenv.isLinux [ 661 (builtins.tryEval ( 662 (service.mkServiceOciImage (ociArgs // { serviceName = "../fixture"; })).outPath 663 )) 664 (builtins.tryEval ( 665 (service.mkServiceOciImage (ociArgs // { package = "not-a-derivation"; })).outPath 666 )) 667 (builtins.tryEval ( 668 (service.mkServiceOciImage (ociArgs // { binaryName = "fixture service"; })).outPath 669 )) 670 (builtins.tryEval ( 671 (service.mkServiceOciImage ( 672 ociArgs 673 // { 674 serviceName = lib.concatStrings (lib.replicate 129 "a"); 675 } 676 )).outPath 677 )) 678 (builtins.tryEval ( 679 (service.mkServiceOciImage ( 680 ociArgs 681 // { 682 binaryName = lib.concatStrings (lib.replicate 129 "b"); 683 } 684 )).outPath 685 )) 686 (builtins.tryEval ( 687 (service.mkServiceOciImage ( 688 ociArgs 689 // { 690 buildInfo = fixtureBuildInfo // { 691 serviceVersion = "bad value"; 692 }; 693 } 694 )).outPath 695 )) 696 (builtins.tryEval ( 697 (service.mkServiceOciImage ( 698 ociArgs 699 // { 700 buildInfo = fixtureBuildInfo // { 701 serviceVersion = lib.concatStrings (lib.replicate 129 "1"); 702 }; 703 } 704 )).outPath 705 )) 706 (builtins.tryEval ( 707 (service.mkServiceOciImage ( 708 ociArgs 709 // { 710 buildInfo = fixtureBuildInfo // { 711 serviceCommit = "ABCDEF"; 712 }; 713 } 714 )).outPath 715 )) 716 (builtins.tryEval ( 717 (service.mkServiceOciImage ( 718 ociArgs 719 // { 720 buildInfo = fixtureBuildInfo // { 721 libRevision = "bad"; 722 }; 723 } 724 )).outPath 725 )) 726 (builtins.tryEval ( 727 (service.mkServiceOciImage ( 728 ociArgs 729 // { 730 buildInfo = fixtureBuildInfo // { 731 rustVersion = "stable"; 732 }; 733 } 734 )).outPath 735 )) 736 (builtins.tryEval ( 737 (service.mkServiceOciImage ( 738 ociArgs 739 // { 740 buildInfo = fixtureBuildInfo // { 741 target = "x86_64-unknown-linux-musl"; 742 }; 743 } 744 )).outPath 745 )) 746 (builtins.tryEval ( 747 (service.mkServiceOciImage ( 748 ociArgs 749 // { 750 buildInfo = fixtureBuildInfo // { 751 featureProfile = "development"; 752 }; 753 } 754 )).outPath 755 )) 756 (builtins.tryEval ( 757 (service.mkServiceOciImage ( 758 ociArgs 759 // { 760 buildInfo = fixtureBuildInfo // { 761 extra = "unexpected"; 762 }; 763 } 764 )).outPath 765 )) 766 (builtins.tryEval ( 767 (service.mkServiceOciImage ( 768 ociArgs 769 // { 770 buildInfo = fixtureBuildInfo // { 771 contractVersions = fixtureBuildInfo.contractVersions // { 772 config = 0; 773 }; 774 }; 775 } 776 )).outPath 777 )) 778 (builtins.tryEval ( 779 (service.mkServiceOciImage ( 780 ociArgs 781 // { 782 buildInfo = fixtureBuildInfo // { 783 contractVersions = fixtureBuildInfo.contractVersions // { 784 config = 4294967296; 785 }; 786 }; 787 } 788 )).outPath 789 )) 790 (builtins.tryEval ( 791 (service.mkServiceOciImage ( 792 ociArgs 793 // { 794 buildInfo = fixtureBuildInfo // { 795 contractVersions = builtins.removeAttrs fixtureBuildInfo.contractVersions [ "provider" ]; 796 }; 797 } 798 )).outPath 799 )) 800 ]; 801 nixosServiceConfig = if pkgs.stdenv.isLinux then nixosService.serviceConfig else null; 802 nixosModuleArguments = { 803 serviceName = "fixture_service"; 804 binaryName = "fixture-service"; 805 packageFor = _: package; 806 commandForInstance = _: [ "--help" ]; 807 }; 808 invalidNixosModuleConstructors = [ 809 (nixosModuleArguments // { serviceName = "../fixture"; }) 810 (nixosModuleArguments // { serviceName = "fixture-service"; }) 811 (nixosModuleArguments // { serviceName = lib.concatStrings (lib.replicate 129 "a"); }) 812 (nixosModuleArguments // { binaryName = "fixture service"; }) 813 (nixosModuleArguments // { binaryName = lib.concatStrings (lib.replicate 129 "b"); }) 814 (nixosModuleArguments // { packageFor = "not-a-function"; }) 815 (nixosModuleArguments // { commandForInstance = "not-a-function"; }) 816 (nixosModuleArguments // { stopTimeoutSeconds = 0; }) 817 (nixosModuleArguments // { stopTimeoutSeconds = 86401; }) 818 (nixosModuleArguments // { addressFamilies = [ ]; }) 819 ( 820 nixosModuleArguments 821 // { 822 addressFamilies = [ 823 "AF_UNIX" 824 "AF_UNIX" 825 ]; 826 } 827 ) 828 (nixosModuleArguments // { addressFamilies = [ "AF_PACKET" ]; }) 829 ]; 830 invalidNixosModuleConstructorResults = map ( 831 arguments: builtins.tryEval ((service.mkServiceNixosModule arguments) { }) 832 ) invalidNixosModuleConstructors; 833 baseNixosModuleConfiguration = { 834 enable = true; 835 inherit package; 836 adminGroup = null; 837 instances.primary = { 838 configurationFile = pkgs.writeText "fixture-service-assertion-config.toml" ""; 839 credentials = { }; 840 }; 841 }; 842 nixosModuleAssertionsPass = 843 module: moduleServiceName: moduleConfiguration: 844 let 845 evaluated = module { 846 config = lib.setAttrByPath [ 847 "services" 848 "radroots" 849 moduleServiceName 850 ] moduleConfiguration; 851 inherit pkgs; 852 }; 853 in 854 lib.all (entry: entry.assertion) evaluated.config.assertions; 855 invalidNixosModuleConfigurations = [ 856 (baseNixosModuleConfiguration // { enable = false; }) 857 (baseNixosModuleConfiguration // { instances = { }; }) 858 (baseNixosModuleConfiguration // { adminGroup = "INVALID GROUP"; }) 859 ( 860 baseNixosModuleConfiguration 861 // { 862 adminGroup = lib.concatStrings (lib.replicate 129 "a"); 863 } 864 ) 865 ( 866 baseNixosModuleConfiguration 867 // { 868 instances = { 869 "../primary" = baseNixosModuleConfiguration.instances.primary; 870 }; 871 } 872 ) 873 ( 874 baseNixosModuleConfiguration 875 // { 876 instances = { 877 ${lib.concatStrings (lib.replicate 129 "a")} = baseNixosModuleConfiguration.instances.primary; 878 }; 879 } 880 ) 881 ( 882 baseNixosModuleConfiguration 883 // { 884 instances.primary.credentials."bad:name" = "/run/operator/token"; 885 } 886 ) 887 ( 888 baseNixosModuleConfiguration 889 // { 890 instances.primary.credentials.token = "relative/token"; 891 } 892 ) 893 ( 894 baseNixosModuleConfiguration 895 // { 896 instances.primary.credentials.token = "/nix/store"; 897 } 898 ) 899 ( 900 baseNixosModuleConfiguration 901 // { 902 instances.primary.credentials.token = "/nix/store/secret"; 903 } 904 ) 905 ( 906 baseNixosModuleConfiguration 907 // { 908 instances.primary.credentials.token = "/run/operator/token:alias"; 909 } 910 ) 911 ( 912 baseNixosModuleConfiguration 913 // { 914 instances.primary.credentials.token = "/run/operator/token\nvalue"; 915 } 916 ) 917 ( 918 baseNixosModuleConfiguration 919 // { 920 instances.primary.credentials.token = "/run//operator/token"; 921 } 922 ) 923 ( 924 baseNixosModuleConfiguration 925 // { 926 instances.primary.credentials.token = "/run/operator/./token"; 927 } 928 ) 929 ( 930 baseNixosModuleConfiguration 931 // { 932 instances.primary.credentials.token = "/run/operator/../token"; 933 } 934 ) 935 ( 936 baseNixosModuleConfiguration 937 // { 938 instances.primary.credentials.token = "/run/operator/token/"; 939 } 940 ) 941 ( 942 baseNixosModuleConfiguration 943 // { 944 instances.primary.credentials.token = "/"; 945 } 946 ) 947 ( 948 baseNixosModuleConfiguration 949 // { 950 instances.primary.credentials.token = "/${lib.concatStrings (lib.replicate 4096 "a")}"; 951 } 952 ) 953 ( 954 baseNixosModuleConfiguration 955 // { 956 instances.primary.credentials = lib.genAttrs (lib.genList ( 957 index: "credential-${toString index}" 958 ) 33) (_: "/run/operator/token"); 959 } 960 ) 961 ( 962 baseNixosModuleConfiguration 963 // { 964 instances = lib.genAttrs (lib.genList (index: "instance-${toString index}") 65) ( 965 _: baseNixosModuleConfiguration.instances.primary 966 ); 967 } 968 ) 969 ]; 970 invalidNixosModuleConfigurationResults = map ( 971 moduleConfiguration: 972 builtins.tryEval (nixosModuleAssertionsPass nixosModule "fixture_service" moduleConfiguration) 973 ) invalidNixosModuleConfigurations; 974 commandNixosModule = 975 command: 976 service.mkServiceNixosModule ( 977 nixosModuleArguments 978 // { 979 commandForInstance = _: command; 980 } 981 ); 982 invalidNixosCommandResults = 983 map 984 ( 985 command: 986 builtins.tryEval ( 987 nixosModuleAssertionsPass (commandNixosModule command) "fixture_service" 988 baseNixosModuleConfiguration 989 ) 990 ) 991 [ 992 (lib.replicate 65 "argument") 993 [ (lib.concatStrings (lib.replicate 4097 "a")) ] 994 [ "argument\nvalue" ] 995 [ "argument\rvalue" ] 996 ]; 997 maximumNixosModule = service.mkServiceNixosModule ( 998 nixosModuleArguments 999 // { 1000 serviceName = lib.concatStrings (lib.replicate 128 "a"); 1001 binaryName = lib.concatStrings (lib.replicate 128 "b"); 1002 stopTimeoutSeconds = 86400; 1003 addressFamilies = [ "AF_UNIX" ]; 1004 } 1005 ); 1006 maximumNixosModuleConfiguration = { 1007 enable = true; 1008 inherit package; 1009 adminGroup = lib.concatStrings (lib.replicate 128 "a"); 1010 instances.${lib.concatStrings (lib.replicate 109 "b")} = { 1011 configurationFile = pkgs.writeText "fixture-service-maximum-config.toml" ""; 1012 credentials = lib.genAttrs (lib.genList (index: "credential-${toString index}") 32) ( 1013 _: "/${lib.concatStrings (lib.replicate 4095 "c")}" 1014 ); 1015 }; 1016 }; 1017 overlongNixosUnitConfiguration = maximumNixosModuleConfiguration // { 1018 instances = { 1019 ${lib.concatStrings (lib.replicate 110 "b")} = baseNixosModuleConfiguration.instances.primary; 1020 }; 1021 }; 1022 overlongNixosUnitResult = builtins.tryEval ( 1023 nixosModuleAssertionsPass maximumNixosModule (lib.concatStrings ( 1024 lib.replicate 128 "a" 1025 )) overlongNixosUnitConfiguration 1026 ); 1027 maximumNixosInstanceCountConfiguration = baseNixosModuleConfiguration // { 1028 instances = lib.genAttrs (lib.genList (index: "instance-${toString index}") 64) ( 1029 _: baseNixosModuleConfiguration.instances.primary 1030 ); 1031 }; 1032 maximumNixosCommandModule = commandNixosModule ( 1033 lib.replicate 64 (lib.concatStrings (lib.replicate 4096 "a")) 1034 ); 1035 noAdminNixosEvaluation = nixosModule { 1036 config = lib.setAttrByPath [ 1037 "services" 1038 "radroots" 1039 "fixture_service" 1040 ] baseNixosModuleConfiguration; 1041 inherit pkgs; 1042 }; 1043 noAdminNixosServiceConfig = 1044 noAdminNixosEvaluation.config.systemd.services.content.${nixosUnitName}.serviceConfig; 1045 in 1046 assert 1047 service.supportedSystems == [ 1048 "aarch64-darwin" 1049 "x86_64-linux" 1050 ]; 1051 assert nativeInputs.nativeBuildInputs == [ pkgs.coreutils ]; 1052 assert nativeInputs.buildInputs == [ ]; 1053 assert nativeInputs.environment.RADROOTS_SERVICE_FIXTURE == "1"; 1054 assert 1055 nativeInputs.environmentContract.RADROOTS_SERVICE_FIXTURE == { 1056 classification = "nonsecret"; 1057 value = "1"; 1058 }; 1059 assert outputs.serviceName == "fixture_service"; 1060 assert outputs.packages.default == package; 1061 assert (pkgs.stdenv.isLinux -> outputs.packages.oci == ociImage); 1062 assert ( 1063 pkgs.stdenv.isLinux 1064 -> 1065 ociImage.meta.platforms == [ 1066 "x86_64-linux" 1067 ] 1068 ); 1069 assert (!pkgs.stdenv.isLinux -> !(builtins.hasAttr "oci" outputs.packages)); 1070 assert outputs.checks == checks; 1071 assert 1072 builtins.attrNames checks == [ 1073 "app-smoke" 1074 "check" 1075 "clippy" 1076 "config" 1077 "docs" 1078 "fmt" 1079 "integration" 1080 ] 1081 ++ lib.optionals pkgs.stdenv.isLinux [ 1082 "nixos-module" 1083 "oci-image" 1084 ] 1085 ++ [ 1086 "package" 1087 "smoke" 1088 "source-lock" 1089 "sqlx" 1090 "test" 1091 ]; 1092 assert checks.package == package; 1093 assert checks.sqlx == hooks.sqlx; 1094 assert checks.config == hooks.config; 1095 assert checks.source-lock == hooks.source-lock; 1096 assert checks.integration == hooks.integration; 1097 assert checks.app-smoke == appSmoke; 1098 assert checks.smoke == smoke; 1099 assert outputs.apps == apps; 1100 assert 1101 builtins.attrNames apps == [ 1102 "default" 1103 "release-acceptance" 1104 ]; 1105 assert apps.default.program == "${package}/bin/fixture-service"; 1106 assert lib.hasSuffix "/bin/fixture_service-release-acceptance" apps.release-acceptance.program; 1107 assert outputs.devShells.default == devShell; 1108 assert devShell.name == "fixture_service-dev-shell"; 1109 assert invalidName.success == false; 1110 assert defaultOverride.success == false; 1111 assert invalidPackage.success == false; 1112 assert invalidNativeInputs.success == false; 1113 assert lib.all (result: result.success == false) invalidNativeInputDefinitions; 1114 assert invalidServicePackage.success == false; 1115 assert invalidBinaryName.success == false; 1116 assert invalidReleaseProfile.success == false; 1117 assert profileOverride.success == false; 1118 assert lib.all (result: result.success == false) invalidHookResults; 1119 assert missingHook.success == false; 1120 assert unexpectedHook.success == false; 1121 assert lib.all (result: result.success == false) weakenedPolicyResults; 1122 assert invalidExtraCheck.success == false; 1123 assert standardOverride.success == false; 1124 assert lib.all (result: result.success == false) invalidAppResults; 1125 assert lib.all (result: result.success == false) invalidDevShellResults; 1126 assert maximumOciResult.success; 1127 assert lib.all (result: result.success == false) invalidOciResults; 1128 assert ( 1129 pkgs.stdenv.isLinux 1130 -> 1131 builtins.attrNames ( 1132 lib.filterAttrs (name: _: lib.hasPrefix "radroots-" name) nixosConfiguration.config.systemd.services 1133 ) == [ nixosUnitName ] 1134 ); 1135 assert (pkgs.stdenv.isLinux -> nixosService.wantedBy == [ "multi-user.target" ]); 1136 assert (pkgs.stdenv.isLinux -> nixosService.wants == [ "network-online.target" ]); 1137 assert (pkgs.stdenv.isLinux -> nixosService.after == [ "network-online.target" ]); 1138 assert (pkgs.stdenv.isLinux -> nixosServiceConfig.Type == "simple"); 1139 assert (pkgs.stdenv.isLinux -> nixosServiceConfig.DynamicUser); 1140 assert (pkgs.stdenv.isLinux -> nixosServiceConfig.RuntimeDirectoryMode == "0750"); 1141 assert ( 1142 pkgs.stdenv.isLinux 1143 -> 1144 nixosServiceConfig.BindReadOnlyPaths == [ 1145 "${nixosConfiguration.config.services.radroots.fixture_service.instances.primary.configurationFile}:/etc/radroots/services/fixture_service/primary/config.toml" 1146 ] 1147 ); 1148 assert ( 1149 pkgs.stdenv.isLinux 1150 -> 1151 nixosServiceConfig.LoadCredential == [ 1152 "api-token:/run/operator/fixture-api-token" 1153 ] 1154 ); 1155 assert (pkgs.stdenv.isLinux -> !(nixosServiceConfig ? MemoryDenyWriteExecute)); 1156 assert (pkgs.stdenv.isLinux -> !(nixosServiceConfig ? SystemCallFilter)); 1157 assert lib.all (result: result.success == false) invalidNixosModuleConstructorResults; 1158 assert lib.all ( 1159 result: result.success && result.value == false 1160 ) invalidNixosModuleConfigurationResults; 1161 assert lib.all (result: result.success && result.value == false) invalidNixosCommandResults; 1162 assert ( 1163 nixosModuleAssertionsPass maximumNixosModule (lib.concatStrings ( 1164 lib.replicate 128 "a" 1165 )) maximumNixosModuleConfiguration 1166 ); 1167 assert (overlongNixosUnitResult.success && overlongNixosUnitResult.value == false); 1168 assert ( 1169 nixosModuleAssertionsPass nixosModule "fixture_service" maximumNixosInstanceCountConfiguration 1170 ); 1171 assert ( 1172 nixosModuleAssertionsPass maximumNixosCommandModule "fixture_service" baseNixosModuleConfiguration 1173 ); 1174 assert noAdminNixosServiceConfig.Group == "radroots-fixture_service"; 1175 assert noAdminNixosServiceConfig.RuntimeDirectoryMode == "0700"; 1176 assert !(noAdminNixosServiceConfig ? SupplementaryGroups); 1177 assert ( 1178 !pkgs.stdenv.isLinux 1179 -> (builtins.tryEval ((service.mkServiceOciImage ociArgs).outPath)).success == false 1180 ); 1181 { 1182 inherit outputs; 1183 }