diff options
author | Pascal Bach | 2023-03-16 20:56:37 +0100 |
---|---|---|
committer | GitHub | 2023-03-16 20:56:37 +0100 |
commit | 7c166f412b29c1620575c34a911b49535bbb63df (patch) | |
tree | 40e003cd0a9317c78613109666bbee07cb64d679 /nixos | |
parent | 0fea9287f4586c19f44f2164f2efd72adc0fbe82 (diff) | |
parent | 740fea3eddfd1b6a8a1f65f32ae3bd0336370f14 (diff) |
Merge pull request #221096 from awakesecurity/minio-paths
nixos/minio: gracefully handle root credentials file
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/services/web-servers/minio.nix | 79 | ||||
-rw-r--r-- | nixos/tests/minio.nix | 84 |
2 files changed, 105 insertions, 58 deletions
diff --git a/nixos/modules/services/web-servers/minio.nix b/nixos/modules/services/web-servers/minio.nix index 1a9eacb431b3..21bec4f63a87 100644 --- a/nixos/modules/services/web-servers/minio.nix +++ b/nixos/modules/services/web-servers/minio.nix @@ -60,7 +60,7 @@ in ''; }; - rootCredentialsFile = mkOption { + rootCredentialsFile = mkOption { type = types.nullOr types.path; default = null; description = lib.mdDoc '' @@ -96,29 +96,62 @@ in config = mkIf cfg.enable { warnings = optional ((cfg.accessKey != "") || (cfg.secretKey != "")) "services.minio.`accessKey` and services.minio.`secretKey` are deprecated, please use services.minio.`rootCredentialsFile` instead."; - systemd.tmpfiles.rules = [ - "d '${cfg.configDir}' - minio minio - -" - ] ++ (map (x: "d '" + x + "' - minio minio - - ") cfg.dataDir); - - systemd.services.minio = { - description = "Minio Object Storage"; - after = [ "network-online.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - ExecStart = "${cfg.package}/bin/minio server --json --address ${cfg.listenAddress} --console-address ${cfg.consoleAddress} --config-dir=${cfg.configDir} ${toString cfg.dataDir}"; - Type = "simple"; - User = "minio"; - Group = "minio"; - LimitNOFILE = 65536; - EnvironmentFile = if (cfg.rootCredentialsFile != null) then cfg.rootCredentialsFile - else if ((cfg.accessKey != "") || (cfg.secretKey != "")) then (legacyCredentials cfg) - else null; + systemd = lib.mkMerge [{ + tmpfiles.rules = [ + "d '${cfg.configDir}' - minio minio - -" + ] ++ (map (x: "d '" + x + "' - minio minio - - ") cfg.dataDir); + + services.minio = { + description = "Minio Object Storage"; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/minio server --json --address ${cfg.listenAddress} --console-address ${cfg.consoleAddress} --config-dir=${cfg.configDir} ${toString cfg.dataDir}"; + Type = "simple"; + User = "minio"; + Group = "minio"; + LimitNOFILE = 65536; + EnvironmentFile = + if (cfg.rootCredentialsFile != null) then cfg.rootCredentialsFile + else if ((cfg.accessKey != "") || (cfg.secretKey != "")) then (legacyCredentials cfg) + else null; + }; + environment = { + MINIO_REGION = "${cfg.region}"; + MINIO_BROWSER = "${if cfg.browser then "on" else "off"}"; + }; }; - environment = { - MINIO_REGION = "${cfg.region}"; - MINIO_BROWSER = "${if cfg.browser then "on" else "off"}"; - }; - }; + } + + (lib.mkIf (cfg.rootCredentialsFile != null) { + # The service will fail if the credentials file is missing + services.minio.unitConfig.ConditionPathExists = cfg.rootCredentialsFile; + + # The service will not restart if the credentials file has + # been changed. This can cause stale root credentials. + paths.minio-root-credentials = { + wantedBy = [ "multi-user.target" ]; + + pathConfig = { + PathChanged = [ cfg.rootCredentialsFile ]; + Unit = "minio-restart.service"; + }; + }; + + services.minio-restart = { + description = "Restart MinIO"; + + script = '' + systemctl restart minio.service + ''; + + serviceConfig = { + Type = "oneshot"; + Restart = "on-failure"; + RestartSec = 5; + }; + }; + })]; users.users.minio = { group = "minio"; diff --git a/nixos/tests/minio.nix b/nixos/tests/minio.nix index ad51f738d490..ece4864f771c 100644 --- a/nixos/tests/minio.nix +++ b/nixos/tests/minio.nix @@ -1,5 +1,5 @@ -import ./make-test-python.nix ({ pkgs, ...} : -let +import ./make-test-python.nix ({ pkgs, ... }: + let accessKey = "BKIKJAA5BMMU2RHO6IBB"; secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12"; minioPythonScript = pkgs.writeScript "minio-test.py" '' @@ -18,41 +18,55 @@ let sio.seek(0) minioClient.put_object('test-bucket', 'test.txt', sio, sio_len, content_type='text/plain') ''; -in { - name = "minio"; - meta = with pkgs.lib.maintainers; { - maintainers = [ bachp ]; - }; + rootCredentialsFile = "/etc/nixos/minio-root-credentials"; + credsPartial = pkgs.writeText "minio-credentials-partial" '' + MINIO_ROOT_USER=${accessKey} + ''; + credsFull = pkgs.writeText "minio-credentials-full" '' + MINIO_ROOT_USER=${accessKey} + MINIO_ROOT_PASSWORD=${secretKey} + ''; + in + { + name = "minio"; + meta = with pkgs.lib.maintainers; { + maintainers = [ bachp ]; + }; - nodes = { - machine = { pkgs, ... }: { - services.minio = { - enable = true; - rootCredentialsFile = pkgs.writeText "minio-credentials" '' - MINIO_ROOT_USER=${accessKey} - MINIO_ROOT_PASSWORD=${secretKey} - ''; - }; - environment.systemPackages = [ pkgs.minio-client ]; + nodes = { + machine = { pkgs, ... }: { + services.minio = { + enable = true; + inherit rootCredentialsFile; + }; + environment.systemPackages = [ pkgs.minio-client ]; - # Minio requires at least 1GiB of free disk space to run. - virtualisation.diskSize = 4 * 1024; + # Minio requires at least 1GiB of free disk space to run. + virtualisation.diskSize = 4 * 1024; + }; }; - }; - testScript = '' - start_all() - machine.wait_for_unit("minio.service") - machine.wait_for_open_port(9000) + testScript = '' + import time + + start_all() + # simulate manually editing root credentials file + machine.wait_for_unit("multi-user.target") + machine.copy_from_host("${credsPartial}", "${rootCredentialsFile}") + time.sleep(3) + machine.copy_from_host("${credsFull}", "${rootCredentialsFile}") - # Create a test bucket on the server - machine.succeed( - "mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4" - ) - machine.succeed("mc mb minio/test-bucket") - machine.succeed("${minioPythonScript}") - assert "test-bucket" in machine.succeed("mc ls minio") - assert "Test from Python" in machine.succeed("mc cat minio/test-bucket/test.txt") - machine.shutdown() - ''; -}) + machine.wait_for_unit("minio.service") + machine.wait_for_open_port(9000) + + # Create a test bucket on the server + machine.succeed( + "mc config host add minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4" + ) + machine.succeed("mc mb minio/test-bucket") + machine.succeed("${minioPythonScript}") + assert "test-bucket" in machine.succeed("mc ls minio") + assert "Test from Python" in machine.succeed("mc cat minio/test-bucket/test.txt") + machine.shutdown() + ''; + }) |