Change:
"ownCloud Infinite Scale Stack" or owncloud rewritten in Go. <!-- Describe the project a little: --Metadata homepage URL: source URL: license: asl20 platforms: unix
There are some hassles to deal with on this one. PNPM usage: Image assets downloaded with curl (and no hashes or revisions) Code generation tools and code repositories downloaded by
Note that ownCloud provide prebuilt binaries for oCIS. It's fairly simple to get these working on NixOS: Perhaps this can be used as a temporary solution until we can build it ourselves?
I used your derivation and opened . I tested it a bit, and will work on a proper module over next few days/weeks, can you share if you are already using above derivation, and if yes, how stable are rc releases?
I've been using the rc for a while and haven't had any major issues. It's probably better to go with the stable release by default though. Perhaps we could package both?
Has the situation changed where the OCIS can be built from source now? I'd rather not use a proprietary binary.

Discussion:
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> <ins> - [ownCloud Infinite Scale Stack](https://owncloud.com/infinite-scale-4-0/), a modern and scalable rewrite of ownCloud. </ins> - [Handheld Daemon](https://github.com/hhd-dev/hhd), support for gaming handhelds like the Legion Go, ROG Ally, and GPD Win. Available as [services.handheld-daemon](#opt-services.handheld-daemon.enable). - [Guix](https://guix.gnu.org), a functional package manager inspired by Nix. Available as [services.guix](#opt-services.guix.enable).

./services/web-apps/nexus.nix ./services/web-apps/nifi.nix ./services/web-apps/node-red.nix <ins> ./services/web-apps/ocis.nix </ins> ./services/web-apps/onlyoffice.nix ./services/web-apps/openvscode-server.nix ./services/web-apps/mobilizon.nix

<ins> # ownCloud Infinite Scale {#module-services-ocis} [ownCloud Infinite Scale](https://owncloud.dev/ocis/) (oCIS) is an open-source, modern file-sync and sharing platform. It is a ground-up rewrite of the well-known PHP based ownCloud server. The server setup can be automated using [services.ocis](#opt-services.ocis.enable). The desktop client is packaged at `pkgs.owncloud-client`. ## Basic usage {#module-services-ocis-basic-usage} oCIS is a golang application and does not require an HTTP server (such as nginx) in front of it, though you may optionally use one if you will. oCIS is configured using a combination of yaml and environment variables. It is recommended to familiarize yourself with upstream's available configuration options and deployment instructions: * [Getting Started](https://owncloud.dev/ocis/getting-started/) * [Configuration](https://owncloud.dev/ocis/config/) * [Basic Setup](https://owncloud.dev/ocis/deployment/basic-remote-setup/) A very basic configuration may look like this: ``` { pkgs, ... }: { services.ocis = { enable = true; configDir = "/etc/ocis/config"; }; } ``` This will start the oCIS server and make it available at `https://localhost:9200` However to make this configuration work you will need generate a configuration. You can do this with: ```console $ nix-shell -p ocis-bin $ mkdir scratch/ $ cd scratch/ $ ocis init --config-path . --admin-password "changeme" ``` You may need to pass `--insecure true` or provide the `OCIS_INSECURE = true;` to [`services.ocis.environment`][mod-envFile], if TLS certificates are generated and managed externally (e.g. if you are using oCIS behind reverse proxy). If you want to manage the config file in your nix configuration, then it is encouraged to use a secrets manager like sops-nix or agenix. Be careful not to write files containing secrets to the globally readable nix store. Please note that current NixOS module for oCIS is configured to run in `fullstack` mode, which starts all the services for owncloud on single instance. This will start multiple ocis services and listen on multiple other ports. Current known services and their ports are as below: | Service            | Group   |  Port | |--------------------|---------|-------| | gateway            | api     |  9142 | | sharing            | api     |  9150 | | app-registry       | api     |  9242 | | ocdav              | web     | 45023 | | auth-machine       | api     |  9166 | | storage-system     | api     |  9215 | | webdav             | web     |  9115 | | webfinger          | web     | 46871 | | storage-system     | web     |  9216 | | web                | web     |  9100 | | eventhistory       | api     | 33177 | | ocs                | web     |  9110 | | storage-publiclink | api     |  9178 | | settings           | web     |  9190 | | ocm                | api     |  9282 | | settings           | api     |  9191 | | ocm                | web     |  9280 | | app-provider       | api     |  9164 | | storage-users      | api     |  9157 | | auth-service       | api     |  9199 | | thumbnails         | web     |  9186 | | thumbnails         | api     |  9185 | | storage-shares     | api     |  9154 | | sse                | sse     | 46833 | | userlog            | userlog | 45363 | | search             | api     |  9220 | | proxy              | web     |  9200 | | idp                | web     |  9130 | | frontend           | web     |  9140 | | groups             | api     |  9160 | | graph              | graph   |  9120 | | users              | api     |  9144 | | auth-basic         | api     |  9146 | ## Configuration via environment variables You can also eschew the config file entirely and pass everything to oCIS via environment variables. For this make use of [`services.ocis.environment`][mod-env] for non-sensitive values, and [`services.ocis.environmentFile`][mod-envFile] for sensitive values. Configuration in (`services.ocis.environment`)[mod-env] overrides those from [`services.ocis.environmentFile`][mod-envFile] and will have highest precedence [mod-env]: #opt-services.ocis.environment [mod-envFile]: #opt-services.ocis.environmentFile </ins>

<ins> { config, lib, pkgs, ... }: let inherit (lib) types; cfg = config.services.ocis; defaultUser = "ocis"; defaultGroup = defaultUser; in { options = { services.ocis = { enable = lib.mkEnableOption "ownCloud Infinite Scale"; package = lib.mkPackageOption pkgs "ocis-bin" { }; configDir = lib.mkOption { type = types.nullOr types.path; default = null; example = "/var/lib/ocis/config"; description = lib.mdDoc '' Path to directory containing oCIS config file. Example config can be generated by `ocis init --config-path fileName --admin-password "adminPass"`. Add `--insecure true` if SSL certificates are generated and managed externally (e.g. using oCIS behind reverse proxy). Note: This directory must contain at least a `ocis.yaml`. Ensure [user](#opt-services.ocis.user) has read/write access to it. In some circumstances you may need to add additional oCIS configuration files (e.g., `proxy.yaml`) to this directory. ''; }; environmentFile = lib.mkOption { type = types.nullOr types.path; default = null; example = "/run/keys/ocis.env"; description = lib.mdDoc '' An environment file as defined in {manpage}`systemd.exec(5)`. Configuration provided in this file will override those from [configDir](#opt-services.ocis.configDir)/ocis.yaml. ''; }; user = lib.mkOption { type = types.str; default = defaultUser; example = "yourUser"; description = lib.mdDoc '' The user to run oCIS as. By default, a user named `${defaultUser}` will be created whose home directory is [stateDir](#opt-services.ocis.stateDir). ''; }; group = lib.mkOption { type = types.str; default = defaultGroup; example = "yourGroup"; description = lib.mdDoc '' The group to run oCIS under. By default, a group named `${defaultGroup}` will be created. ''; }; address = lib.mkOption { type = types.str; default = "127.0.0.1"; description = "Web interface address."; }; port = lib.mkOption { type = types.port; default = 9200; description = "Web interface port."; }; url = lib.mkOption { type = types.str; default = "https://localhost:9200"; example = "https://some-hostname-or-ip:9200"; description = "Web interface address."; }; stateDir = lib.mkOption { default = "/var/lib/ocis"; type = types.str; description = "ownCloud data directory."; }; environment = lib.mkOption { type = types.attrsOf types.str; default = { }; description = lib.mdDoc '' Extra config options. See [the documentation](https://doc.owncloud.com/ocis/next/deployment/services/services.html) for available options. See [notes for environment variables](https://doc.owncloud.com/ocis/next/deployment/services/env-var-note.html) for more information. Note that all the attributes here will be copied to /nix/store/ and will be world readable. Options like *_PASSWORD or *_SECRET should be part of     [environmentFile](#opt-services.ocis.environmentFile) instead, and are only provided here for illustrative purpose. Configuration here will override those from [environmentFile](#opt-services.ocis.environmentFile) and will have highest precedence, at the cost of security. Do NOT put security sensitive stuff here. ''; example = { OCIS_INSECURE = "false"; OCIS_LOG_LEVEL = "error"; OCIS_JWT_SECRET = "super_secret"; OCIS_TRANSFER_SECRET = "foo"; OCIS_MACHINE_AUTH_API_KEY = "foo"; OCIS_SYSTEM_USER_ID = "123"; OCIS_MOUNT_ID = "123"; OCIS_STORAGE_USERS_MOUNT_ID = "123"; GATEWAY_STORAGE_USERS_MOUNT_ID = "123"; CS3_ALLOW_INSECURE = "true"; OCIS_INSECURE_BACKENDS = "true"; TLS_INSECURE = "true"; TLS_SKIP_VERIFY_CLIENT_CERT = "true"; WEBDAV_ALLOW_INSECURE = "true"; IDP_TLS = "false"; GRAPH_APPLICATION_ID = "1234"; IDM_IDPSVC_PASSWORD = "password"; IDM_REVASVC_PASSWORD = "password"; IDM_SVC_PASSWORD = "password"; IDP_ISS = "https://localhost:9200"; OCIS_LDAP_BIND_PASSWORD = "password"; OCIS_SERVICE_ACCOUNT_ID = "foo"; OCIS_SERVICE_ACCOUNT_SECRET = "foo"; OCIS_SYSTEM_USER_API_KEY = "foo"; STORAGE_USERS_MOUNT_ID = "123"; }; }; }; }; config = lib.mkIf cfg.enable { users.users.${defaultUser} = lib.mkIf (cfg.user == defaultUser) { group = cfg.group; home = cfg.stateDir; isSystemUser = true; createHome = true; description = "ownCloud Infinite Scale daemon user"; }; users.groups = lib.mkIf (cfg.group == defaultGroup) { ${defaultGroup} = { }; }; systemd = { services.ocis = { description = "ownCloud Infinite Scale Stack"; wantedBy = [ "multi-user.target" ]; environment = { PROXY_HTTP_ADDR = "${cfg.address}:${toString cfg.port}"; OCIS_URL = cfg.url; OCIS_CONFIG_DIR = if (cfg.configDir == null) then "${cfg.stateDir}/config" else cfg.configDir; OCIS_BASE_DATA_PATH = cfg.stateDir; } // cfg.environment; serviceConfig = { Type = "simple"; ExecStart = "${lib.getExe cfg.package} server"; WorkingDirectory = cfg.stateDir; User = cfg.user; Group = cfg.group; Restart = "always"; EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; ReadWritePaths = [ cfg.stateDir ]; ReadOnlyPaths = [ cfg.configDir ]; MemoryDenyWriteExecute = true; NoNewPrivileges = true; PrivateTmp = true; PrivateDevices = true; ProtectSystem = "strict"; ProtectHome = true; ProtectControlGroups = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectKernelLogs = true; RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ]; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; LockPersonality = true; SystemCallArchitectures = "native"; }; }; }; }; meta.maintainers = with lib.maintainers; [ bhankas danth ramblurr ]; } </ins>

nvmetcfg = handleTest ./nvmetcfg.nix {}; nzbget = handleTest ./nzbget.nix {}; nzbhydra2 = handleTest ./nzbhydra2.nix {}; <ins> ocis = handleTest ./ocis.nix {}; </ins> oh-my-zsh = handleTest ./oh-my-zsh.nix {}; ollama = handleTest ./ollama.nix {}; ombi = handleTest ./ombi.nix {};

<ins> import ./make-test-python.nix ( { lib, pkgs, ... }: let # this is a demo user created by IDM_CREATE_DEMO_USERS=true demoUser = "einstein"; demoPassword = "relativity"; adminUser = "admin"; adminPassword = "hunter2"; testRunner = pkgs.writers.writePython3Bin "test-runner" { libraries = [ pkgs.python3Packages.selenium ]; flakeIgnore = [ "E501" ]; } '' import sys from selenium.webdriver.common.by import By from selenium.webdriver import Firefox from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options = Options() options.add_argument('--headless') driver = Firefox(options=options) user = sys.argv[1] password = sys.argv[2] driver.implicitly_wait(20) driver.get('https://localhost:9200/login') wait = WebDriverWait(driver, 10) wait.until(EC.title_contains("Sign in")) driver.find_element(By.XPATH, '//*[@id="oc-login-username"]').send_keys(user) driver.find_element(By.XPATH, '//*[@id="oc-login-password"]').send_keys(password) driver.find_element(By.XPATH, '//*[@id="root"]//button').click() wait.until(EC.title_contains("Personal")) ''; # This was generated with `ocis init --config-path testconfig/ --admin-password "hunter2" --insecure true`. testConfig = '' token_manager: jwt_secret: kaKYgfso*d9GA-yTM.&BTOUEuMz%Ai0H machine_auth_api_key: sGWRG1JZ&qe&pe@N1HKK4#qH*B&@xLnO system_user_api_key: h+m4aHPUtOtUJFKrc5B2=04C=7fDZaT- transfer_secret: 4-R6AfUjQn0P&+h2+$skf0lJqmre$j=x system_user_id: db180e0a-b38a-4edf-a4cd-a3d358248537 admin_user_id: ea623f50-742d-4fd0-95bb-c61767b070d4 graph: application: id: 11971eab-d560-4b95-a2d4-50726676bbd0 events: tls_insecure: true spaces: insecure: true identity: ldap: bind_password: ^F&Vn7@mYGYGuxr$#qm^gGy@FVq=.w=y service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE idp: ldap: bind_password: bv53IjS28x.nxth*%aRbE70%4TGNXbLU idm: service_user_passwords: admin_password: hunter2 idm_password: ^F&Vn7@mYGYGuxr$#qm^gGy@FVq=.w=y reva_password: z-%@fWipLliR8lD#fl.0teC#9QbhJ^eb idp_password: bv53IjS28x.nxth*%aRbE70%4TGNXbLU proxy: oidc: insecure: true insecure_backends: true service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE frontend: app_handler: insecure: true archiver: insecure: true service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE auth_basic: auth_providers: ldap: bind_password: z-%@fWipLliR8lD#fl.0teC#9QbhJ^eb auth_bearer: auth_providers: oidc: insecure: true users: drivers: ldap: bind_password: z-%@fWipLliR8lD#fl.0teC#9QbhJ^eb groups: drivers: ldap: bind_password: z-%@fWipLliR8lD#fl.0teC#9QbhJ^eb ocdav: insecure: true ocm: service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE thumbnails: thumbnail: transfer_secret: 2%11!zAu*AYE&=d*8dfoZs8jK&5ZMm*% webdav_allow_insecure: true cs3_allow_insecure: true search: events: tls_insecure: true service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE audit: events: tls_insecure: true settings: service_account_ids: - df39a290-3f3e-4e39-b67b-8b810ca2abac sharing: events: tls_insecure: true storage_users: events: tls_insecure: true mount_id: ef72cb8b-809c-4592-bfd2-1df603295205 service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE notifications: notifications: events: tls_insecure: true service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE nats: nats: tls_skip_verify_client_cert: true gateway: storage_registry: storage_users_mount_id: ef72cb8b-809c-4592-bfd2-1df603295205 userlog: service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE auth_service: service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE clientlog: service_account: service_account_id: df39a290-3f3e-4e39-b67b-8b810ca2abac service_account_secret: .demKypQ$=pGl+yRar!#YaFjLYCr4YwE''; in { name = "ocis"; meta.maintainers = with lib.maintainers; [ bhankas ramblurr ]; nodes.machine = { config, ... }: { virtualisation.memorySize = 2048; environment.systemPackages = [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ]; # if you do this in production, dont put secrets in this file because it will be written to the world readable nix store environment.etc."ocis/ocis.env".text = '' ADMIN_PASSWORD=${adminPassword} IDM_CREATE_DEMO_USERS=true ''; # if you do this in production, dont put secrets in this file because it will be written to the world readable nix store environment.etc."ocis/config/ocis.yaml".text = testConfig; services.ocis = { enable = true; configDir = "/etc/ocis/config"; environment = { OCIS_INSECURE = "true"; }; environmentFile = "/etc/ocis/ocis.env"; }; }; testScript = '' start_all() machine.wait_for_unit("ocis.service") machine.wait_for_open_port(9200) # wait for ocis to fully come up machine.sleep(5) with subtest("ocis bin works"): machine.succeed("${lib.getExe pkgs.ocis-bin} version") with subtest("use the web interface to log in with a demo user"): machine.succeed("PYTHONUNBUFFERED=1 systemd-cat -t test-runner test-runner ${demoUser} ${demoPassword}") with subtest("use the web interface to log in with the provisioned admin user"): machine.succeed("PYTHONUNBUFFERED=1 systemd-cat -t test-runner test-runner ${adminUser} ${adminPassword}") ''; } ) </ins>

<ins> { fetchurl, lib, stdenv, autoPatchelfHook, }: stdenv.mkDerivation (finalAttrs: { pname = "ocis-bin"; version = "5.0.0"; system = if stdenv.isLinux && stdenv.isx86_64 then "linux-amd64" else if stdenv.isLinux && stdenv.isAarch64 then "linux-arm64" else ""; src = fetchurl { url = "https://github.com/owncloud/ocis/releases/download/v${finalAttrs.version}/ocis-${finalAttrs.version}-${finalAttrs.system}"; hash = if stdenv.isLinux && stdenv.isAarch64 then "sha256-xRgDNwmRovXbyGQ5sTUw5srsXMBDYyBFMpB9MoXoo+w=" else if stdenv.isLinux && stdenv.isx86_64 then "sha256-0lgDIHldW67OwinfYPATXkWUZVnR3PoXC4XLM1KkKmY=" else builtins.throw "Unsupported platform, please contact Nixpkgs maintainers for ocis package"; }; dontUnpack = true; nativeBuildInputs = [ autoPatchelfHook ]; installPhase = '' runHook preInstall install -D $src $out/bin/ocis runHook postInstall ''; meta = with lib; { description = "ownCloud Infinite Scale Stack "; homepage = "https://owncloud.dev/ocis/"; changelog = "https://github.com/owncloud/ocis/releases/tag/v${version}"; # oCIS is licensed under non-free EULA which can be found here : # https://github.com/owncloud/ocis/releases/download/v5.0.0/End-User-License-Agreement-for-ownCloud-Infinite-Scale.pdf license = licenses.unfree; maintainers = with maintainers; [ ramblurr bhankas danth ramblurr ]; sourceProvenance = [ sourceTypes.binaryNativeCode ]; mainProgram = "ocis"; }; }) </ins>