Unverified Commit 7bd2d2bb authored by oddlama's avatar oddlama Committed by GitHub
Browse files

nixos/ente: migrate test from minio to garage, minor fixes (#509708)

parents 494ff408 98d5ac25
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1544,6 +1544,21 @@
  "module-services-emacs-man-pages": [
    "index.html#module-services-emacs-man-pages"
  ],
  "module-services-ente": [
    "index.html#module-services-ente"
  ],
  "module-services-ente-quickstart": [
    "index.html#module-services-ente-quickstart"
  ],
  "module-services-ente-registering-users": [
    "index.html#module-services-ente-registering-users"
  ],
  "module-services-ente-increasing-storage-limit": [
    "index.html#module-services-ente-increasing-storage-limit"
  ],
  "module-services-ente-ios-background-sync": [
    "index.html#module-services-ente-ios-background-sync"
  ],
  "module-services-livebook": [
    "index.html#module-services-livebook"
  ],
+12 −54
Original line number Diff line number Diff line
@@ -6,57 +6,20 @@ end-to-end encrypted platform for photos and videos.
## Quickstart {#module-services-ente-quickstart}

To host ente, you need the following things:
- S3 storage server (either external or self-hosted like [minio](https://github.com/minio/minio))
- An S3-compatible object storage server (either an external provider or a
  self-hosted one such as [garage](#module-services-garage)). From your
  storage provider you will need:
  - the S3 endpoint URL
  - a bucket name
  - an access key ID and secret access key with read/write access to the bucket
- Several subdomains pointing to your server:
  - accounts.example.com
  - albums.example.com
  - api.example.com
  - cast.example.com
  - photos.example.com
  - s3.example.com

The following example shows how to setup ente with a self-hosted S3 storage via minio.
You can host the minio s3 storage on the same server as ente, but as this isn't
a requirement the example shows the minio and ente setup separately.
We assume that the minio server will be reachable at `https://s3.example.com`.

```nix
{
  services.minio = {
    enable = true;
    # ente's config must match this region!
    region = "us-east-1";
    # Please use a file, agenix or sops-nix to securely store your root user password!
    # MINIO_ROOT_USER=your_root_user
    # MINIO_ROOT_PASSWORD=a_randomly_generated_long_password
    rootCredentialsFile = "/run/secrets/minio-credentials-full";
  };

  systemd.services.minio.environment.MINIO_SERVER_URL = "https://s3.example.com";

  # Proxy for minio
  networking.firewall.allowedTCPPorts = [
    80
    443
  ];
  services.nginx = {
    recommendedProxySettings = true;
    virtualHosts."s3.example.com" = {
      forceSSL = true;
      useACME = true;
      locations."/".proxyPass = "http://localhost:9000";
      # determine max file upload size
      extraConfig = ''
        client_max_body_size 16G;
        proxy_buffering off;
        proxy_request_buffering off;
      '';
    };
  };
}
```

And the configuration for ente:
Once you have an S3 endpoint, bucket and credentials, configure ente as follows:

```nix
{
@@ -84,11 +47,13 @@ And the configuration for ente:
        s3 = {
          use_path_style_urls = true;
          b2-eu-cen = {
            # The S3 endpoint, bucket and credentials from your storage provider
            endpoint = "https://s3.example.com";
            # Must be us-east-1 as it is required internally by ente
            region = "us-east-1";
            bucket = "ente";
            key._secret = pkgs.writeText "minio_user" "minio_user";
            secret._secret = pkgs.writeText "minio_pw" "minio_pw";
            key._secret = "/run/secrets/s3-access-key-id";
            secret._secret = "/run/secrets/s3-secret-access-key";
          };
        };
        key = {
@@ -122,13 +87,6 @@ If you have a mail server or smtp relay, you can optionally configure
`services.ente.api.settings.smtp` so ente can send you emails (registration code and possibly
other events). This is optional.

After starting the minio server, make sure the bucket exists:

```
mc alias set minio https://s3.example.com root_user root_password --api s3v4
mc mb -p minio/ente
```

Now ente should be ready to go under `https://photos.example.com`.

## Registering users {#module-services-ente-registering-users}
@@ -157,7 +115,7 @@ available. While adding new plans is possible in theory, it requires some
manual database operations which isn't worthwhile. Instead, use `ente-cli`
with your admin user to modify the storage limit.

## iOS background sync
## iOS background sync {#module-services-ente-ios-background-sync}

On iOS, background sync is achived via a silent notification sent by the server
every 30 minutes that allows the phone to sync for about 30 seconds, enough for
+4 −1
Original line number Diff line number Diff line
@@ -359,5 +359,8 @@ in
    })
  ];

  meta.maintainers = with lib.maintainers; [ oddlama ];
  meta = {
    doc = ./ente.md;
    maintainers = with lib.maintainers; [ oddlama ];
  };
}
+34 −25
Original line number Diff line number Diff line
{ lib, pkgs, ... }:
let
  accessKey = "BKIKJAA5BMMU2RHO6IBB";
  secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
  rootCredentialsFile = pkgs.writeText "minio-credentials-full" ''
    MINIO_ROOT_USER=${accessKey}
    MINIO_ROOT_PASSWORD=${secretKey}
  '';
  garageAccessKey = "GKaaaaaaaaaaaaaaaaaaaaaaaa";
  garageSecretKey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

  certs = import ./snakeoil-certs.nix;
  domain = certs.domain;
@@ -14,22 +10,29 @@ in
  name = "ente";
  meta.maintainers = [ lib.maintainers.oddlama ];

  nodes.minio =
  nodes.garage =
    { ... }:
    {
      environment.systemPackages = [ pkgs.minio-client ];
      services.minio = {
      services.garage = {
        enable = true;
        inherit rootCredentialsFile;
        package = pkgs.garage_2;
        settings = {
          replication_factor = 1;
          consistency_mode = "consistent";
          rpc_bind_addr = "[::]:3901";
          rpc_public_addr = "[::1]:3901";
          rpc_secret = "5c1915fa04d0b6739675c61bf5907eb0fe3d9c69850c83820f51b4d25d13868c";
          s3_api = {
            s3_region = "us-east-1";
            api_bind_addr = "[::]:3900";
          };
        };
      };

      networking.firewall.allowedTCPPorts = [
        9000
      ];
      networking.firewall.allowedTCPPorts = [ 3900 ];

      systemd.services.minio.environment = {
        MINIO_SERVER_URL = "https://s3.${domain}";
      };
      # Garage requires at least 1GiB of free disk space to run.
      virtualisation.diskSize = 2 * 1024;
    };

  nodes.ente =
@@ -71,7 +74,7 @@ in
              forceSSL = true;
              sslCertificate = certs.${domain}.cert;
              sslCertificateKey = certs.${domain}.key;
              locations."/".proxyPass = "http://${nodes.minio.networking.primaryIPAddress}:9000";
              locations."/".proxyPass = "http://${nodes.garage.networking.primaryIPAddress}:3900";
              extraConfig = ''
                client_max_body_size 32M;
                proxy_buffering off;
@@ -103,8 +106,8 @@ in
                endpoint = "https://s3.${domain}";
                region = "us-east-1";
                bucket = "ente";
                key._secret = pkgs.writeText "accesskey" accessKey;
                secret._secret = pkgs.writeText "secretkey" secretKey;
                key._secret = pkgs.writeText "accesskey" garageAccessKey;
                secret._secret = pkgs.writeText "secretkey" garageSecretKey;
              };
            };
            key = {
@@ -118,13 +121,19 @@ in
    };

  testScript = ''
    minio.start()
    minio.wait_for_unit("minio.service")
    minio.wait_for_open_port(9000)
    garage.start()
    garage.wait_for_unit("garage.service")
    garage.wait_for_open_port(3900)

    # Configure the cluster layout
    garage_node_id = garage.succeed("garage status | tail -n1 | awk '{ print $1 }'")
    garage.succeed(f"garage layout assign -c 1G -z garage {garage_node_id}")
    garage.succeed("garage layout apply --version 1")

    # Create a test bucket on the server
    minio.succeed("mc alias set minio http://localhost:9000 ${accessKey} ${secretKey} --api s3v4")
    minio.succeed("mc mb -p minio/ente")
    # Import the predefined API key and create the bucket
    garage.succeed("garage key import ${garageAccessKey} ${garageSecretKey} --yes")
    garage.succeed("garage bucket create ente")
    garage.succeed("garage bucket allow --read --write ente --key ${garageAccessKey}")

    # Start ente
    ente.start()
+48 −46
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
  nodejs,
  rustPlatform,
  rustc,
  sd,
  wasm-bindgen-cli_0_2_108,
  wasm-pack,
  yarnConfigHook,
@@ -21,6 +22,7 @@
  # can set this parameter to override these occurrences with your own url. Must include the schema.
  # Example: https://my-ente.example.com
  enteMainUrl ? null,
  nixosTests,
}:

stdenv.mkDerivation (finalAttrs: {
@@ -81,16 +83,13 @@ stdenv.mkDerivation (finalAttrs: {
        packages/wasm/package.json \
        --replace-fail "wasm-pack " ${lib.escapeShellArg "${wasm-pack}/bin/wasm-pack "}
    ''
    # Replace hardcoded ente.io urls if desired
    # Replace hardcoded links pointing to the public ente instance so that
    # users of a self-hosted instance are not accidentally redirected there
    + lib.optionalString (enteMainUrl != null) ''
      substituteInPlace \
        apps/payments/src/services/billing.ts \
        apps/photos/src/pages/shared-albums.tsx \
        --replace-fail "https://ente.io" ${lib.escapeShellArg enteMainUrl}

      substituteInPlace \
        apps/accounts/src/pages/index.tsx \
        --replace-fail "https://web.ente.io" ${lib.escapeShellArg enteMainUrl}
      for pattern in "https://web.ente.io" "https://ente.com" "https://ente.io"; do
        mapfile -d "" -t files < <(grep -rlFZ -- "$pattern" apps/)
        ${lib.getExe sd} -F -- "$pattern" ${lib.escapeShellArg enteMainUrl} "''${files[@]}"
      done
    '';

  yarnBuildScript = "build:${enteApp}";
@@ -106,7 +105,9 @@ stdenv.mkDerivation (finalAttrs: {
      runHook postInstall
    '';

  passthru.updateScript = writeScript "update-ente-web" ''
  passthru = {
    tests = { inherit (nixosTests) ente; };
    updateScript = writeScript "update-ente-web" ''
      #!/usr/bin/env nix-shell
      #!nix-shell -i bash -p coreutils nix-update gnugrep gnused curl

@@ -157,6 +158,7 @@ stdenv.mkDerivation (finalAttrs: {

      echo "Successfully updated wasm-bindgen-cli to $wasm_bindgen_attr"
    '';
  };

  meta = {
    description = "Ente application web frontends";