| @@ -44,20 +44,7 @@ in { | ||
| ### implementation | ||
|
|
||
| config = mkIf cfg.enable { | ||
| services.udev.packages = [ pkgs.trezor-udev-rules ]; | ||
|
|
||
| systemd.services.trezord = { | ||
| description = "TREZOR Bridge"; | ||
| @@ -34,10 +34,7 @@ with lib; | ||
|
|
||
| services.dbus.packages = [ pkgs.udisks2 ]; | ||
|
|
||
| systemd.tmpfiles.rules = [ "d /var/lib/udisks2 0755 root root -" ]; | ||
|
|
||
| services.udev.packages = [ pkgs.udisks2 ]; | ||
|
|
||
| @@ -0,0 +1,97 @@ | ||
| { config, lib, pkgs, ...} : | ||
|
|
||
| with lib; | ||
|
|
||
| let | ||
| cfg = config.services.orangefs.client; | ||
|
|
||
| in { | ||
| ###### interface | ||
|
|
||
| options = { | ||
| services.orangefs.client = { | ||
| enable = mkEnableOption "OrangeFS client daemon"; | ||
|
|
||
| extraOptions = mkOption { | ||
| type = with types; listOf str; | ||
| default = []; | ||
| description = "Extra command line options for pvfs2-client."; | ||
| }; | ||
|
|
||
| fileSystems = mkOption { | ||
| description = '' | ||
| The orangefs file systems to be mounted. | ||
| This option is prefered over using <option>fileSystems</option> directly since | ||
| the pvfs client service needs to be running for it to be mounted. | ||
| ''; | ||
|
|
||
| example = [{ | ||
| mountPoint = "/orangefs"; | ||
| target = "tcp://server:3334/orangefs"; | ||
| }]; | ||
|
|
||
| type = with types; listOf (submodule ({ ... } : { | ||
| options = { | ||
|
|
||
| mountPoint = mkOption { | ||
| type = types.str; | ||
| default = "/orangefs"; | ||
| description = "Mount point."; | ||
| }; | ||
|
|
||
| options = mkOption { | ||
| type = with types; listOf str; | ||
| default = []; | ||
| description = "Mount options"; | ||
| }; | ||
|
|
||
| target = mkOption { | ||
| type = types.str; | ||
| default = null; | ||
| example = "tcp://server:3334/orangefs"; | ||
| description = "Target URL"; | ||
| }; | ||
| }; | ||
| })); | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
|
|
||
| ###### implementation | ||
|
|
||
| config = mkIf cfg.enable { | ||
| environment.systemPackages = [ pkgs.orangefs ]; | ||
|
|
||
| boot.supportedFilesystems = [ "pvfs2" ]; | ||
| boot.kernelModules = [ "orangefs" ]; | ||
|
|
||
| systemd.services.orangefs-client = { | ||
| requires = [ "network-online.target" ]; | ||
| after = [ "network-online.target" ]; | ||
|
|
||
| serviceConfig = { | ||
| Type = "simple"; | ||
|
|
||
| ExecStart = '' | ||
| ${pkgs.orangefs}/bin/pvfs2-client-core \ | ||
| --logtype=syslog ${concatStringsSep " " cfg.extraOptions} | ||
| ''; | ||
|
|
||
| TimeoutStopSec = "120"; | ||
| }; | ||
| }; | ||
|
|
||
| systemd.mounts = map (fs: { | ||
| requires = [ "orangefs-client.service" ]; | ||
| after = [ "orangefs-client.service" ]; | ||
| bindsTo = [ "orangefs-client.service" ]; | ||
| wantedBy = [ "remote-fs.target" ]; | ||
| type = "pvfs2"; | ||
| options = concatStringsSep "," fs.options; | ||
| what = fs.target; | ||
| where = fs.mountPoint; | ||
| }) cfg.fileSystems; | ||
| }; | ||
| } | ||
|
|
| @@ -0,0 +1,225 @@ | ||
| { config, lib, pkgs, ...} : | ||
|
|
||
| with lib; | ||
|
|
||
| let | ||
| cfg = config.services.orangefs.server; | ||
|
|
||
| aliases = mapAttrsToList (alias: url: alias) cfg.servers; | ||
|
|
||
| # Maximum handle number is 2^63 | ||
| maxHandle = 9223372036854775806; | ||
|
|
||
| # One range of handles for each meta/data instance | ||
| handleStep = maxHandle / (length aliases) / 2; | ||
|
|
||
| fileSystems = mapAttrsToList (name: fs: '' | ||
| <FileSystem> | ||
| Name ${name} | ||
| ID ${toString fs.id} | ||
| RootHandle ${toString fs.rootHandle} | ||
| ${fs.extraConfig} | ||
| <MetaHandleRanges> | ||
| ${concatStringsSep "\n" ( | ||
| imap0 (i: alias: | ||
| let | ||
| begin = i * handleStep + 3; | ||
| end = begin + handleStep - 1; | ||
| in "Range ${alias} ${toString begin}-${toString end}") aliases | ||
| )} | ||
| </MetaHandleRanges> | ||
| <DataHandleRanges> | ||
| ${concatStringsSep "\n" ( | ||
| imap0 (i: alias: | ||
| let | ||
| begin = i * handleStep + 3 + (length aliases) * handleStep; | ||
| end = begin + handleStep - 1; | ||
| in "Range ${alias} ${toString begin}-${toString end}") aliases | ||
| )} | ||
| </DataHandleRanges> | ||
| <StorageHints> | ||
| TroveSyncMeta ${if fs.troveSyncMeta then "yes" else "no"} | ||
| TroveSyncData ${if fs.troveSyncData then "yes" else "no"} | ||
| ${fs.extraStorageHints} | ||
| </StorageHints> | ||
| </FileSystem> | ||
| '') cfg.fileSystems; | ||
|
|
||
| configFile = '' | ||
| <Defaults> | ||
| LogType ${cfg.logType} | ||
| DataStorageSpace ${cfg.dataStorageSpace} | ||
| MetaDataStorageSpace ${cfg.metadataStorageSpace} | ||
| BMIModules ${concatStringsSep "," cfg.BMIModules} | ||
| ${cfg.extraDefaults} | ||
| </Defaults> | ||
| ${cfg.extraConfig} | ||
| <Aliases> | ||
| ${concatStringsSep "\n" (mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)} | ||
| </Aliases> | ||
| ${concatStringsSep "\n" fileSystems} | ||
| ''; | ||
|
|
||
| in { | ||
| ###### interface | ||
|
|
||
| options = { | ||
| services.orangefs.server = { | ||
| enable = mkEnableOption "OrangeFS server"; | ||
|
|
||
| logType = mkOption { | ||
| type = with types; enum [ "file" "syslog" ]; | ||
| default = "syslog"; | ||
| description = "Destination for log messages."; | ||
| }; | ||
|
|
||
| dataStorageSpace = mkOption { | ||
| type = types.str; | ||
| default = null; | ||
| example = "/data/storage"; | ||
| description = "Directory for data storage."; | ||
| }; | ||
|
|
||
| metadataStorageSpace = mkOption { | ||
| type = types.str; | ||
| default = null; | ||
| example = "/data/meta"; | ||
| description = "Directory for meta data storage."; | ||
| }; | ||
|
|
||
| BMIModules = mkOption { | ||
| type = with types; listOf str; | ||
| default = [ "bmi_tcp" ]; | ||
| example = [ "bmi_tcp" "bmi_ib"]; | ||
| description = "List of BMI modules to load."; | ||
| }; | ||
|
|
||
| extraDefaults = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Extra config for <literal><Defaults></literal> section."; | ||
| }; | ||
|
|
||
| extraConfig = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Extra config for the global section."; | ||
| }; | ||
|
|
||
| servers = mkOption { | ||
| type = with types; attrsOf types.str; | ||
| default = {}; | ||
| example = '' | ||
| { | ||
| node1="tcp://node1:3334"; | ||
| node2="tcp://node2:3334"; | ||
| } | ||
| ''; | ||
| description = "URLs for storage server including port. The attribute names define the server alias."; | ||
| }; | ||
|
|
||
| fileSystems = mkOption { | ||
| description = '' | ||
| These options will create the <literal><FileSystem></literal> sections of config file. | ||
| ''; | ||
| default = { orangefs = {}; }; | ||
| defaultText = literalExample "{ orangefs = {}; }"; | ||
| example = literalExample '' | ||
| { | ||
| fs1 = { | ||
| id = 101; | ||
| }; | ||
| fs2 = { | ||
| id = 102; | ||
| }; | ||
| } | ||
| ''; | ||
| type = with types; attrsOf (submodule ({ ... } : { | ||
| options = { | ||
| id = mkOption { | ||
| type = types.int; | ||
| default = 1; | ||
| description = "File system ID (must be unique within configuration)."; | ||
| }; | ||
|
|
||
| rootHandle = mkOption { | ||
| type = types.int; | ||
| default = 3; | ||
| description = "File system root ID."; | ||
| }; | ||
|
|
||
| extraConfig = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Extra config for <literal><FileSystem></literal> section."; | ||
| }; | ||
|
|
||
| troveSyncMeta = mkOption { | ||
| type = types.bool; | ||
| default = true; | ||
| description = "Sync meta data."; | ||
| }; | ||
|
|
||
| troveSyncData = mkOption { | ||
| type = types.bool; | ||
| default = false; | ||
| description = "Sync data."; | ||
| }; | ||
|
|
||
| extraStorageHints = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Extra config for <literal><StorageHints></literal> section."; | ||
| }; | ||
| }; | ||
| })); | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| ###### implementation | ||
|
|
||
| config = mkIf cfg.enable { | ||
| environment.systemPackages = [ pkgs.orangefs ]; | ||
|
|
||
| # orangefs daemon will run as user | ||
| users.users.orangefs.isSystemUser = true; | ||
| users.groups.orangefs = {}; | ||
|
|
||
| # To format the file system the config file is needed. | ||
| environment.etc."orangefs/server.conf" = { | ||
| text = configFile; | ||
| user = "orangefs"; | ||
| group = "orangefs"; | ||
| }; | ||
|
|
||
| systemd.services.orangefs-server = { | ||
| wantedBy = [ "multi-user.target" ]; | ||
| requires = [ "network-online.target" ]; | ||
| after = [ "network-online.target" ]; | ||
|
|
||
| serviceConfig = { | ||
| # Run as "simple" in forground mode. | ||
| # This is more reliable | ||
| ExecStart = '' | ||
| ${pkgs.orangefs}/bin/pvfs2-server -d \ | ||
| /etc/orangefs/server.conf | ||
| ''; | ||
| TimeoutStopSec = "120"; | ||
| User = "orangefs"; | ||
| Group = "orangefs"; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| } |
| @@ -0,0 +1,30 @@ | ||
| { config, lib, pkgs, ... }: | ||
|
|
||
| with lib; | ||
| let | ||
| cfg = config.services.go-shadowsocks2.server; | ||
| in { | ||
| options.services.go-shadowsocks2.server = { | ||
| enable = mkEnableOption "go-shadowsocks2 server"; | ||
|
|
||
| listenAddress = mkOption { | ||
| type = types.str; | ||
| description = "Server listen address or URL"; | ||
| example = "ss://AEAD_CHACHA20_POLY1305:your-password@:8488"; | ||
| }; | ||
| }; | ||
|
|
||
| config = mkIf cfg.enable { | ||
| systemd.services.go-shadowsocks2-server = { | ||
| description = "go-shadowsocks2 server"; | ||
|
|
||
| after = [ "network.target" ]; | ||
| wantedBy = [ "multi-user.target" ]; | ||
|
|
||
| serviceConfig = { | ||
| ExecStart = "${pkgs.go-shadowsocks2}/bin/go-shadowsocks2 -s '${cfg.listenAddress}'"; | ||
| DynamicUser = true; | ||
| }; | ||
| }; | ||
| }; | ||
| } |
| @@ -0,0 +1,193 @@ | ||
| { config, lib, pkgs, ... }: | ||
| with lib; | ||
| let | ||
| cfg = config.services.yggdrasil; | ||
| configProvided = (cfg.config != {}); | ||
| configAsFile = (if configProvided then | ||
| toString (pkgs.writeTextFile { | ||
| name = "yggdrasil-conf"; | ||
| text = builtins.toJSON cfg.config; | ||
| }) | ||
| else null); | ||
| configFileProvided = (cfg.configFile != null); | ||
| generateConfig = ( | ||
| if configProvided && configFileProvided then | ||
| "${pkgs.jq}/bin/jq -s add /run/yggdrasil/configFile.json ${configAsFile}" | ||
| else if configProvided then | ||
| "cat ${configAsFile}" | ||
| else if configFileProvided then | ||
| "cat /run/yggdrasil/configFile.json" | ||
| else | ||
| "${cfg.package}/bin/yggdrasil -genconf" | ||
| ); | ||
|
|
||
| in { | ||
| options = with types; { | ||
| services.yggdrasil = { | ||
| enable = mkEnableOption "the yggdrasil system service"; | ||
|
|
||
| configFile = mkOption { | ||
| type = nullOr str; | ||
| default = null; | ||
| example = "/run/keys/yggdrasil.conf"; | ||
| description = '' | ||
| A file which contains JSON configuration for yggdrasil. | ||
| You do not have to supply a complete configuration, as | ||
| yggdrasil will use default values for anything which is | ||
| omitted. If the encryption and signing keys are omitted, | ||
| yggdrasil will generate new ones each time the service is | ||
| started, resulting in a random IPv6 address on the yggdrasil | ||
| network each time. | ||
| If both this option and <option>config</option> are | ||
| supplied, they will be combined, with values from | ||
| <option>config</option> taking precedence. | ||
| You can use the command <code>nix-shell -p yggdrasil --run | ||
| "yggdrasil -genconf -json"</code> to generate a default | ||
| JSON configuration. | ||
| ''; | ||
| }; | ||
|
|
||
| config = mkOption { | ||
| type = attrs; | ||
| default = {}; | ||
| example = { | ||
| Peers = [ | ||
| "tcp://aa.bb.cc.dd:eeeee" | ||
| "tcp://[aaaa:bbbb:cccc:dddd::eeee]:fffff" | ||
| ]; | ||
| Listen = [ | ||
| "tcp://0.0.0.0:xxxxx" | ||
| ]; | ||
| }; | ||
| description = '' | ||
| Configuration for yggdrasil, as a Nix attribute set. | ||
| Warning: this is stored in the WORLD-READABLE Nix store! | ||
| Therefore, it is not appropriate for private keys. If you | ||
| do not specify the keys, yggdrasil will generate a new set | ||
| each time the service is started, creating a random IPv6 | ||
| address on the yggdrasil network each time. | ||
| If you wish to specify the keys, use | ||
| <option>configFile</option>. If both | ||
| <option>configFile</option> and <option>config</option> are | ||
| supplied, they will be combined, with values from | ||
| <option>config</option> taking precedence. | ||
| You can use the command <code>nix-shell -p yggdrasil --run | ||
| "yggdrasil -genconf"</code> to generate default | ||
| configuration values with documentation. | ||
| ''; | ||
| }; | ||
|
|
||
| openMulticastPort = mkOption { | ||
| type = bool; | ||
| default = false; | ||
| description = '' | ||
| Whether to open the UDP port used for multicast peer | ||
| discovery. The NixOS firewall blocks link-local | ||
| communication, so in order to make local peering work you | ||
| will also need to set <code>LinkLocalTCPPort</code> in your | ||
| yggdrasil configuration (<option>config</option> or | ||
| <option>configFile</option>) to a port number other than 0, | ||
| and then add that port to | ||
| <option>networking.firewall.allowedTCPPorts</option>. | ||
| ''; | ||
| }; | ||
|
|
||
| denyDhcpcdInterfaces = mkOption { | ||
| type = listOf str; | ||
| default = []; | ||
| example = [ "tap*" ]; | ||
| description = '' | ||
| Disable the DHCP client for any interface whose name matches | ||
| any of the shell glob patterns in this list. Use this | ||
| option to prevent the DHCP client from broadcasting requests | ||
| on the yggdrasil network. It is only necessary to do so | ||
| when yggdrasil is running in TAP mode, because TUN | ||
| interfaces do not support broadcasting. | ||
| ''; | ||
| }; | ||
|
|
||
| package = mkOption { | ||
| type = package; | ||
| default = pkgs.yggdrasil; | ||
| defaultText = "pkgs.yggdrasil"; | ||
| description = "Yggdrasil package to use."; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| config = mkIf cfg.enable { | ||
| assertions = [ | ||
| { assertion = config.networking.enableIPv6; | ||
| message = "networking.enableIPv6 must be true for yggdrasil to work"; | ||
| } | ||
| ]; | ||
|
|
||
| environment.etc."yggdrasil.conf" = { | ||
| enable = true; | ||
| mode = "symlink"; | ||
| source = "/run/yggdrasil/yggdrasil.conf"; | ||
| }; | ||
|
|
||
| systemd.services.yggdrasil = { | ||
| description = "Yggdrasil Network Service"; | ||
| path = [ cfg.package ] ++ optional (configProvided && configFileProvided) pkgs.jq; | ||
| bindsTo = [ "network-online.target" ]; | ||
| after = [ "network-online.target" ]; | ||
| wantedBy = [ "multi-user.target" ]; | ||
|
|
||
| preStart = '' | ||
| ${generateConfig} | yggdrasil -normaliseconf -useconf > /run/yggdrasil/yggdrasil.conf | ||
| ''; | ||
|
|
||
| serviceConfig = { | ||
| ExecStart = "${cfg.package}/bin/yggdrasil -useconffile /etc/yggdrasil.conf"; | ||
| ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; | ||
| Restart = "always"; | ||
|
|
||
| RuntimeDirectory = "yggdrasil"; | ||
| RuntimeDirectoryMode = "0700"; | ||
| BindReadOnlyPaths = mkIf configFileProvided | ||
| [ "${cfg.configFile}:/run/yggdrasil/configFile.json" ]; | ||
|
|
||
| # TODO: as of yggdrasil 0.3.8 and systemd 243, yggdrasil fails | ||
| # to set up the network adapter when DynamicUser is set. See | ||
| # github.com/yggdrasil-network/yggdrasil-go/issues/557. The | ||
| # following options are implied by DynamicUser according to | ||
| # the systemd.exec documentation, and can be removed if the | ||
| # upstream issue is fixed and DynamicUser is set to true: | ||
| PrivateTmp = true; | ||
| RemoveIPC = true; | ||
| NoNewPrivileges = true; | ||
| ProtectSystem = "strict"; | ||
| RestrictSUIDSGID = true; | ||
| # End of list of options implied by DynamicUser. | ||
|
|
||
| AmbientCapabilities = "CAP_NET_ADMIN"; | ||
| CapabilityBoundingSet = "CAP_NET_ADMIN"; | ||
| MemoryDenyWriteExecute = true; | ||
| ProtectControlGroups = true; | ||
| ProtectHome = "tmpfs"; | ||
| ProtectKernelModules = true; | ||
| ProtectKernelTunables = true; | ||
| RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; | ||
| RestrictNamespaces = true; | ||
| RestrictRealtime = true; | ||
| SystemCallArchitectures = "native"; | ||
| SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @resources"; | ||
| }; | ||
| }; | ||
|
|
||
| networking.dhcpcd.denyInterfaces = cfg.denyDhcpcdInterfaces; | ||
| networking.firewall.allowedUDPPorts = mkIf cfg.openMulticastPort [ 9001 ]; | ||
|
|
||
| # Make yggdrasilctl available on the command line. | ||
| environment.systemPackages = [ cfg.package ]; | ||
| }; | ||
| meta.maintainers = with lib.maintainers; [ gazally ]; | ||
| } |
| @@ -0,0 +1,49 @@ | ||
| { pkgs, lib, config, ... }: | ||
|
|
||
| with lib; | ||
|
|
||
| let | ||
| cfg = config.services.gotify; | ||
| in { | ||
| options = { | ||
| services.gotify = { | ||
| enable = mkEnableOption "Gotify webserver"; | ||
|
|
||
| port = mkOption { | ||
| type = types.port; | ||
| description = '' | ||
| Port the server listens to. | ||
| ''; | ||
| }; | ||
|
|
||
| stateDirectoryName = mkOption { | ||
| type = types.str; | ||
| default = "gotify-server"; | ||
| description = '' | ||
| The name of the directory below <filename>/var/lib</filename> where | ||
| gotify stores its runtime data. | ||
| ''; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| config = mkIf cfg.enable { | ||
| systemd.services.gotify-server = { | ||
| wantedBy = [ "multi-user.target" ]; | ||
| after = [ "network.target" ]; | ||
| description = "Simple server for sending and receiving messages"; | ||
|
|
||
| environment = { | ||
| GOTIFY_SERVER_PORT = toString cfg.port; | ||
| }; | ||
|
|
||
| serviceConfig = { | ||
| WorkingDirectory = "/var/lib/${cfg.stateDirectoryName}"; | ||
| StateDirectory = cfg.stateDirectoryName; | ||
| Restart = "always"; | ||
| DynamicUser = "yes"; | ||
| ExecStart = "${pkgs.gotify-server}/bin/server"; | ||
| }; | ||
| }; | ||
| }; | ||
| } |
| @@ -1,27 +1,9 @@ | ||
| { lib, nodes, pkgs, ... }: let | ||
| letsencrypt-ca = nodes.letsencrypt.config.test-support.letsencrypt.caCert; | ||
| in { | ||
| networking.nameservers = [ | ||
| nodes.letsencrypt.config.networking.primaryIPAddress | ||
| ]; | ||
|
|
||
| security.pki.certificateFiles = [ letsencrypt-ca ]; | ||
| } |
| @@ -1,7 +1,7 @@ | ||
| { pkgs ? import <nixpkgs> {} | ||
| , lib ? pkgs.lib | ||
|
|
||
| , domains ? [ "acme-v02.api.letsencrypt.org" "letsencrypt.org" ] | ||
| }: | ||
|
|
||
| pkgs.runCommand "letsencrypt-snakeoil-ca" { | ||
| @@ -0,0 +1,25 @@ | ||
| import ./make-test.nix ({ pkgs, ... } : { | ||
| name = "fancontrol"; | ||
|
|
||
| machine = | ||
| { ... }: | ||
| { hardware.fancontrol.enable = true; | ||
| hardware.fancontrol.config = '' | ||
| INTERVAL=42 | ||
| DEVPATH=hwmon1=devices/platform/dummy | ||
| DEVNAME=hwmon1=dummy | ||
| FCTEMPS=hwmon1/device/pwm1=hwmon1/device/temp1_input | ||
| FCFANS=hwmon1/device/pwm1=hwmon1/device/fan1_input | ||
| MINTEMP=hwmon1/device/pwm1=25 | ||
| MAXTEMP=hwmon1/device/pwm1=65 | ||
| MINSTART=hwmon1/device/pwm1=150 | ||
| MINSTOP=hwmon1/device/pwm1=0 | ||
| ''; | ||
| }; | ||
|
|
||
| # This configuration cannot be valid for the test VM, so it's expected to get an 'outdated' error. | ||
| testScript = '' | ||
| $machine->waitForUnit("fancontrol.service"); | ||
| $machine->waitUntilSucceeds("journalctl -eu fancontrol | grep 'Configuration appears to be outdated'"); | ||
| ''; | ||
| }) |
| @@ -0,0 +1,45 @@ | ||
| import ./make-test.nix ({ pkgs, lib, ...} : { | ||
| name = "gotify-server"; | ||
| meta = with pkgs.stdenv.lib.maintainers; { | ||
| maintainers = [ ma27 ]; | ||
| }; | ||
|
|
||
| machine = { pkgs, ... }: { | ||
| environment.systemPackages = [ pkgs.jq ]; | ||
|
|
||
| services.gotify = { | ||
| enable = true; | ||
| port = 3000; | ||
| }; | ||
| }; | ||
|
|
||
| testScript = '' | ||
| startAll; | ||
| $machine->waitForUnit("gotify-server"); | ||
| $machine->waitForOpenPort(3000); | ||
| my $token = $machine->succeed( | ||
| "curl --fail -sS -X POST localhost:3000/application -F name=nixos " . | ||
| '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' . | ||
| '| jq .token | xargs echo -n' | ||
| ); | ||
| my $usertoken = $machine->succeed( | ||
| "curl --fail -sS -X POST localhost:3000/client -F name=nixos " . | ||
| '-H "Authorization: Basic $(echo -ne "admin:admin" | base64 --wrap 0)" ' . | ||
| '| jq .token | xargs echo -n' | ||
| ); | ||
| $machine->succeed( | ||
| "curl --fail -sS -X POST 'localhost:3000/message?token=$token' -H 'Accept: application/json' " . | ||
| '-F title=Gotify -F message=Works' | ||
| ); | ||
| my $title = $machine->succeed( | ||
| "curl --fail -sS 'localhost:3000/message?since=0&token=$usertoken' | jq '.messages|.[0]|.title' | xargs echo -n" | ||
| ); | ||
| $title eq "Gotify" or die "Wrong title ($title), expected 'Gotify'!"; | ||
| ''; | ||
| }) |
| @@ -0,0 +1,43 @@ | ||
| { system ? builtins.currentSystem, config ? { } | ||
| , pkgs ? import ../.. { inherit system config; } }: | ||
|
|
||
| with import ../lib/testing.nix { inherit system pkgs; }; | ||
| with pkgs.lib; | ||
|
|
||
| let | ||
| matomoTest = package: | ||
| makeTest { | ||
| machine = { config, pkgs, ... }: { | ||
| services.matomo = { | ||
| package = package; | ||
| enable = true; | ||
| nginx = { | ||
| forceSSL = false; | ||
| enableACME = false; | ||
| }; | ||
| }; | ||
| services.mysql = { | ||
| enable = true; | ||
| package = pkgs.mysql; | ||
| }; | ||
| services.nginx.enable = true; | ||
| }; | ||
|
|
||
| testScript = '' | ||
| startAll; | ||
| $machine->waitForUnit("mysql.service"); | ||
| $machine->waitForUnit("phpfpm-matomo.service"); | ||
| $machine->waitForUnit("nginx.service"); | ||
| $machine->succeed("curl -sSfL http://localhost/ | grep '<title>Matomo[^<]*Installation'"); | ||
| ''; | ||
| }; | ||
| in { | ||
| matomo = matomoTest pkgs.matomo // { | ||
| name = "matomo"; | ||
| meta.maintainers = with maintainers; [ florianjacob kiwi mmilata ]; | ||
| }; | ||
| matomo-beta = matomoTest pkgs.matomo-beta // { | ||
| name = "matomo-beta"; | ||
| meta.maintainers = with maintainers; [ florianjacob kiwi mmilata ]; | ||
| }; | ||
| } |
| @@ -0,0 +1,36 @@ | ||
| import ./make-test.nix ({ pkgs, ...} : { | ||
| name = "openarena"; | ||
| meta = with pkgs.stdenv.lib.maintainers; { | ||
| maintainers = [ tomfitzhenry ]; | ||
| }; | ||
|
|
||
| machine = | ||
| { pkgs, ... }: | ||
|
|
||
| { imports = []; | ||
| environment.systemPackages = with pkgs; [ | ||
| socat | ||
| ]; | ||
| services.openarena = { | ||
| enable = true; | ||
| extraFlags = [ | ||
| "+set dedicated 2" | ||
| "+set sv_hostname 'My NixOS server'" | ||
| "+map oa_dm1" | ||
| ]; | ||
| }; | ||
| }; | ||
|
|
||
| testScript = | ||
| '' | ||
| $machine->waitForUnit("openarena.service"); | ||
| $machine->waitUntilSucceeds("ss --numeric --udp --listening | grep -q 27960"); | ||
| # The log line containing 'resolve address' is last and only message that occurs after | ||
| # the server starts accepting clients. | ||
| $machine->waitUntilSucceeds("journalctl -u openarena.service | grep 'resolve address: dpmaster.deathmask.net'"); | ||
| # Check it's possible to join the server. | ||
| $machine->succeed("echo -n -e '\\xff\\xff\\xff\\xffgetchallenge' | socat - UDP4-DATAGRAM:127.0.0.1:27960 | grep -q challengeResponse"); | ||
| ''; | ||
| }) |
| @@ -0,0 +1,88 @@ | ||
| import ./make-test.nix ({ ... } : | ||
|
|
||
| let | ||
| server = { pkgs, ... } : { | ||
| networking.firewall.allowedTCPPorts = [ 3334 ]; | ||
| boot.initrd.postDeviceCommands = '' | ||
| ${pkgs.e2fsprogs}/bin/mkfs.ext4 -L data /dev/vdb | ||
| ''; | ||
|
|
||
| virtualisation.emptyDiskImages = [ 4096 ]; | ||
|
|
||
| fileSystems = pkgs.lib.mkVMOverride | ||
| [ { mountPoint = "/data"; | ||
| device = "/dev/disk/by-label/data"; | ||
| fsType = "ext4"; | ||
| } | ||
| ]; | ||
|
|
||
| services.orangefs.server = { | ||
| enable = true; | ||
| dataStorageSpace = "/data/storage"; | ||
| metadataStorageSpace = "/data/meta"; | ||
| servers = { | ||
| server1 = "tcp://server1:3334"; | ||
| server2 = "tcp://server2:3334"; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| client = { lib, ... } : { | ||
| networking.firewall.enable = true; | ||
|
|
||
| services.orangefs.client = { | ||
| enable = true; | ||
| fileSystems = [{ | ||
| target = "tcp://server1:3334/orangefs"; | ||
| mountPoint = "/orangefs"; | ||
| }]; | ||
| }; | ||
| }; | ||
|
|
||
| in { | ||
| name = "orangefs"; | ||
|
|
||
| nodes = { | ||
| server1 = server; | ||
| server2 = server; | ||
|
|
||
| client1 = client; | ||
| client2 = client; | ||
| }; | ||
|
|
||
| testScript = '' | ||
| # format storage | ||
| foreach my $server (($server1,$server2)) | ||
| { | ||
| $server->start(); | ||
| $server->waitForUnit("multi-user.target"); | ||
| $server->succeed("mkdir -p /data/storage /data/meta"); | ||
| $server->succeed("chown orangefs:orangefs /data/storage /data/meta"); | ||
| $server->succeed("chmod 0770 /data/storage /data/meta"); | ||
| $server->succeed("sudo -g orangefs -u orangefs pvfs2-server -f /etc/orangefs/server.conf"); | ||
| } | ||
| # start services after storage is formated on all machines | ||
| foreach my $server (($server1,$server2)) | ||
| { | ||
| $server->succeed("systemctl start orangefs-server.service"); | ||
| } | ||
| # Check if clients can reach and mount the FS | ||
| foreach my $client (($client1,$client2)) | ||
| { | ||
| $client->start(); | ||
| $client->waitForUnit("orangefs-client.service"); | ||
| # Both servers need to be reachable | ||
| $client->succeed("pvfs2-check-server -h server1 -f orangefs -n tcp -p 3334"); | ||
| $client->succeed("pvfs2-check-server -h server2 -f orangefs -n tcp -p 3334"); | ||
| $client->waitForUnit("orangefs.mount"); | ||
| } | ||
| # R/W test between clients | ||
| $client1->succeed("echo test > /orangefs/file1"); | ||
| $client2->succeed("grep test /orangefs/file1"); | ||
| ''; | ||
| }) |
| @@ -0,0 +1,123 @@ | ||
| let | ||
| aliceIp6 = "200:3b91:b2d8:e708:fbf3:f06:fdd5:90d0"; | ||
| aliceKeys = { | ||
| EncryptionPublicKey = "13e23986fe76bc3966b42453f479bc563348b7ff76633b7efcb76e185ec7652f"; | ||
| EncryptionPrivateKey = "9f86947b15e86f9badac095517a1982e39a2db37ca726357f95987b898d82208"; | ||
| SigningPublicKey = "e2c43349083bc1e998e4ec4535b4c6a8f44ca9a5a8e07336561267253b2be5f4"; | ||
| SigningPrivateKey = "fe3add8da35316c05f6d90d3ca79bd2801e6ccab6d37e5339fef4152589398abe2c43349083bc1e998e4ec4535b4c6a8f44ca9a5a8e07336561267253b2be5f4"; | ||
| }; | ||
| bobIp6 = "201:ebbd:bde9:f138:c302:4afa:1fb6:a19a"; | ||
| bobConfig = { | ||
| InterfacePeers = { | ||
| eth1 = [ "tcp://192.168.1.200:12345" ]; | ||
| }; | ||
| MulticastInterfaces = [ "eth1" ]; | ||
| LinkLocalTCPPort = 54321; | ||
| EncryptionPublicKey = "c99d6830111e12d1b004c52fe9e5a2eef0f6aefca167aca14589a370b7373279"; | ||
| EncryptionPrivateKey = "2e698a53d3fdce5962d2ff37de0fe77742a5c8b56cd8259f5da6aa792f6e8ba3"; | ||
| SigningPublicKey = "de111da0ec781e45bf6c63ecb45a78c24d7d4655abfaeea83b26c36eb5c0fd5b"; | ||
| SigningPrivateKey = "2a6c21550f3fca0331df50668ffab66b6dce8237bcd5728e571e8033b363e247de111da0ec781e45bf6c63ecb45a78c24d7d4655abfaeea83b26c36eb5c0fd5b"; | ||
| }; | ||
|
|
||
| in import ./make-test.nix ({ pkgs, ...} : { | ||
| name = "yggdrasil"; | ||
| meta = with pkgs.stdenv.lib.maintainers; { | ||
| maintainers = [ gazally ]; | ||
| }; | ||
|
|
||
| nodes = rec { | ||
| # Alice is listening for peerings on a specified port, | ||
| # but has multicast peering disabled. Alice has part of her | ||
| # yggdrasil config in Nix and part of it in a file. | ||
| alice = | ||
| { ... }: | ||
| { | ||
| networking = { | ||
| interfaces.eth1.ipv4.addresses = [{ | ||
| address = "192.168.1.200"; | ||
| prefixLength = 24; | ||
| }]; | ||
| firewall.allowedTCPPorts = [ 80 12345 ]; | ||
| }; | ||
| services.httpd.enable = true; | ||
| services.httpd.adminAddr = "foo@example.org"; | ||
|
|
||
| services.yggdrasil = { | ||
| enable = true; | ||
| config = { | ||
| Listen = ["tcp://0.0.0.0:12345"]; | ||
| MulticastInterfaces = [ ]; | ||
| }; | ||
| configFile = toString (pkgs.writeTextFile { | ||
| name = "yggdrasil-alice-conf"; | ||
| text = builtins.toJSON aliceKeys; | ||
| }); | ||
| }; | ||
| }; | ||
|
|
||
| # Bob is set up to peer with Alice, and also to do local multicast | ||
| # peering. Bob's yggdrasil config is in a file. | ||
| bob = | ||
| { ... }: | ||
| { | ||
| networking.firewall.allowedTCPPorts = [ 54321 ]; | ||
| services.yggdrasil = { | ||
| enable = true; | ||
| openMulticastPort = true; | ||
| configFile = toString (pkgs.writeTextFile { | ||
| name = "yggdrasil-bob-conf"; | ||
| text = builtins.toJSON bobConfig; | ||
| }); | ||
| }; | ||
| }; | ||
|
|
||
| # Carol only does local peering. Carol's yggdrasil config is all Nix. | ||
| carol = | ||
| { ... }: | ||
| { | ||
| networking.firewall.allowedTCPPorts = [ 43210 ]; | ||
| services.yggdrasil = { | ||
| enable = true; | ||
| denyDhcpcdInterfaces = [ "ygg0" ]; | ||
| config = { | ||
| IfTAPMode = true; | ||
| IFName = "ygg0"; | ||
| MulticastInterfaces = [ "eth1" ]; | ||
| LinkLocalTCPPort = 43210; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
|
|
||
| testScript = | ||
| '' | ||
| # Give Alice a head start so she is ready when Bob calls. | ||
| $alice->start; | ||
| $alice->waitForUnit("yggdrasil.service"); | ||
| $bob->start; | ||
| $carol->start; | ||
| $bob->waitForUnit("yggdrasil.service"); | ||
| $carol->waitForUnit("yggdrasil.service"); | ||
| $carol->waitUntilSucceeds("[ `ip -o -6 addr show dev ygg0 scope global | grep -v tentative | wc -l` -ge 1 ]"); | ||
| my $carolIp6 = (split /[ \/]+/, $carol->succeed("ip -o -6 addr show dev ygg0 scope global"))[3]; | ||
| # If Alice can talk to Carol, then Bob's outbound peering and Carol's | ||
| # local peering have succeeded and everybody is connected. | ||
| $alice->waitUntilSucceeds("ping -c 1 $carolIp6"); | ||
| $alice->succeed("ping -c 1 ${bobIp6}"); | ||
| $bob->succeed("ping -c 1 ${aliceIp6}"); | ||
| $bob->succeed("ping -c 1 $carolIp6"); | ||
| $carol->succeed("ping -c 1 ${aliceIp6}"); | ||
| $carol->succeed("ping -c 1 ${bobIp6}"); | ||
| $carol->fail("journalctl -u dhcpcd | grep ygg0"); | ||
| $alice->waitForUnit("httpd.service"); | ||
| $carol->succeed("curl --fail -g http://[${aliceIp6}]"); | ||
| ''; | ||
| }) |
| @@ -0,0 +1,71 @@ | ||
| { stdenv | ||
| , fetchFromGitLab | ||
| , cairo | ||
| , dbus | ||
| , desktop-file-utils | ||
| , gettext | ||
| , glib | ||
| , gtk3 | ||
| , libhandy | ||
| , meson | ||
| , ninja | ||
| , pango | ||
| , pkgconfig | ||
| , python3 | ||
| , rustc | ||
| , rustPlatform | ||
| , wrapGAppsHook | ||
| }: | ||
|
|
||
| rustPlatform.buildRustPackage rec { | ||
| pname = "contrast"; | ||
| version = "0.0.2"; | ||
|
|
||
| src = fetchFromGitLab { | ||
| domain = "gitlab.gnome.org"; | ||
| group = "World"; | ||
| owner = "design"; | ||
| repo = "contrast"; | ||
| rev = version; | ||
| sha256 = "0rm705zrk9rfv31pwbqxrswi5v6vhnghxa8dgxjmcrh00l8dm6j9"; | ||
| }; | ||
|
|
||
| cargoSha256 = "06vgc89d93fhjcyy9d1v6lf8kr34pl5bbpwbv2jpfahpj9y84bgj"; | ||
|
|
||
| nativeBuildInputs = [ | ||
| desktop-file-utils | ||
| gettext | ||
| meson | ||
| ninja | ||
| pkgconfig | ||
| python3 | ||
| wrapGAppsHook | ||
| ]; | ||
|
|
||
| buildInputs = [ | ||
| cairo | ||
| dbus | ||
| glib | ||
| gtk3 | ||
| libhandy | ||
| pango | ||
| ]; | ||
|
|
||
| postPatch = '' | ||
| patchShebangs build-aux/meson_post_install.py | ||
| ''; | ||
|
|
||
| # Don't use buildRustPackage phases, only use it for rust deps setup | ||
| configurePhase = null; | ||
| buildPhase = null; | ||
| checkPhase = null; | ||
| installPhase = null; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| description = "Checks whether the contrast between two colors meet the WCAG requirements"; | ||
| homepage = https://gitlab.gnome.org/World/design/contrast; | ||
| license = licenses.gpl3; | ||
| maintainers = with maintainers; [ jtojnar ]; | ||
| }; | ||
| } | ||
|
|
| @@ -0,0 +1,28 @@ | ||
| { stdenv, fetchFromGitHub, xorg, cairo, lv2, pkgconfig }: | ||
|
|
||
| stdenv.mkDerivation rec { | ||
| pname = "BSEQuencer"; | ||
| version = "0.4"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "sjaehn"; | ||
| repo = pname; | ||
| rev = "v${version}"; | ||
| sha256 = "0c3bm2z6z2bjjv1cy50383zr81h99rcb2frmxad0r7lhi27mjyqn"; | ||
| }; | ||
|
|
||
| nativeBuildInputs = [ pkgconfig ]; | ||
| buildInputs = [ | ||
| xorg.libX11 cairo lv2 | ||
| ]; | ||
|
|
||
| installFlags = [ "PREFIX=$(out)" ]; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| homepage = https://github.com/sjaehn/BSEQuencer; | ||
| description = "Multi channel MIDI step sequencer LV2 plugin"; | ||
| maintainers = [ maintainers.magnetophon ]; | ||
| platforms = platforms.linux; | ||
| license = licenses.gpl3; | ||
| }; | ||
| } |
| @@ -0,0 +1,28 @@ | ||
| { stdenv, fetchFromGitHub, xorg, cairo, lv2, pkgconfig }: | ||
|
|
||
| stdenv.mkDerivation rec { | ||
| pname = "BShapr"; | ||
| version = "0.4"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "sjaehn"; | ||
| repo = pname; | ||
| rev = "v${version}"; | ||
| sha256 = "02b4wdfhr9y7z2k6ls086gv3vz4sjf7b1k8ryh573bzd8nr4896v"; | ||
| }; | ||
|
|
||
| nativeBuildInputs = [ pkgconfig ]; | ||
| buildInputs = [ | ||
| xorg.libX11 cairo lv2 | ||
| ]; | ||
|
|
||
| installFlags = [ "PREFIX=$(out)" ]; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| homepage = https://github.com/sjaehn/BShapr; | ||
| description = "Beat / envelope shaper LV2 plugin"; | ||
| maintainers = [ maintainers.magnetophon ]; | ||
| platforms = platforms.linux; | ||
| license = licenses.gpl3; | ||
| }; | ||
| } |
| @@ -0,0 +1,28 @@ | ||
| { stdenv, fetchFromGitHub, xorg, cairo, lv2, pkgconfig }: | ||
|
|
||
| stdenv.mkDerivation rec { | ||
| pname = "BSlizr"; | ||
| version = "1.2.0"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "sjaehn"; | ||
| repo = pname; | ||
| rev = "${version}"; | ||
| sha256 = "1xqhpppfj47nzmyksbqgfvvi5j807g96hqla544w2f752zz4yi0s"; | ||
| }; | ||
|
|
||
| nativeBuildInputs = [ pkgconfig ]; | ||
| buildInputs = [ | ||
| xorg.libX11 cairo lv2 | ||
| ]; | ||
|
|
||
| installFlags = [ "PREFIX=$(out)" ]; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| homepage = https://github.com/sjaehn/BSlizr; | ||
| description = "Sequenced audio slicing effect LV2 plugin (step sequencer effect)"; | ||
| maintainers = [ maintainers.magnetophon ]; | ||
| platforms = platforms.linux; | ||
| license = licenses.gpl3; | ||
| }; | ||
| } |
| @@ -0,0 +1,13 @@ | ||
| diff --git i/Cargo.lock w/Cargo.lock | ||
| index e1eae72..e004898 100644 | ||
| --- i/Cargo.lock | ||
| +++ w/Cargo.lock | ||
| @@ -1310,7 +1310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
|
|
||
| [[package]] | ||
| name = "spotify-tui" | ||
| -version = "0.7.5" | ||
| +version = "0.8.0" | ||
| dependencies = [ | ||
| "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", | ||
| "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", |
| @@ -0,0 +1,16 @@ | ||
| diff --git a/src/main.cpp b/src/main.cpp | ||
| index 0954ae6..a8299f7 100644 | ||
| --- a/src/main.cpp | ||
| +++ b/src/main.cpp | ||
| @@ -162,11 +162,6 @@ int main(int argc, char* argv[]) { | ||
| INFO("Initializing app"); | ||
| appInit(); | ||
|
|
||
| - const char* openedFilename = glfwGetOpenedFilename(); | ||
| - if (openedFilename) { | ||
| - patchPath = openedFilename; | ||
| - } | ||
| - | ||
| if (!settings::headless) { | ||
| APP->patch->init(patchPath); | ||
| } |
| @@ -10,9 +10,6 @@ buildGoPackage rec { | ||
| propagatedBuildInputs = | ||
| stdenv.lib.optionals stdenv.isDarwin [ libobjc IOKit ]; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "ethereum"; | ||
| repo = pname; | ||
| @@ -0,0 +1,53 @@ | ||
| { stdenv, fetchFromGitHub | ||
| , cmake, wrapGAppsHook | ||
| , libX11, xorg, libzip, glfw, gnome3 | ||
| }: | ||
|
|
||
| stdenv.mkDerivation rec { | ||
| pname = "tev"; | ||
| version = "1.13"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "Tom94"; | ||
| repo = pname; | ||
| rev = "v${version}"; | ||
| fetchSubmodules = true; | ||
| sha256 = "0c8md6yv1q449aszs05xfby6a2aiw8pac7x0zs169i5mpqrrbfa9"; | ||
| }; | ||
|
|
||
| nativeBuildInputs = [ cmake wrapGAppsHook ]; | ||
| buildInputs = [ libX11 libzip glfw ] | ||
| ++ (with xorg; [ libXrandr libXinerama libXcursor libXi libXxf86vm ]); | ||
|
|
||
| dontWrapGApps = true; # We also need zenity (see below) | ||
|
|
||
| postPatch = '' | ||
| substituteInPlace CMakeLists.txt \ | ||
| --replace "/usr/" "''${out}/" | ||
| ''; | ||
|
|
||
| postInstall = '' | ||
| wrapProgram $out/bin/tev \ | ||
| "''${gappsWrapperArgs[@]}" \ | ||
| --prefix PATH ":" "${gnome3.zenity}/bin" | ||
| ''; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| description = "A high dynamic range (HDR) image comparison tool"; | ||
| longDescription = '' | ||
| A high dynamic range (HDR) image comparison tool for graphics people. tev | ||
| allows viewing images through various tonemapping operators and inspecting | ||
| the values of individual pixels. Often, it is important to find exact | ||
| differences between pairs of images. For this purpose, tev allows rapidly | ||
| switching between opened images and visualizing various error metrics (L1, | ||
| L2, and relative versions thereof). To avoid clutter, opened images and | ||
| their layers can be filtered by keywords. | ||
| While the predominantly supported file format is OpenEXR certain other | ||
| types of images can also be loaded. | ||
| ''; | ||
| inherit (src.meta) homepage; | ||
| license = licenses.bsd3; | ||
| platforms = platforms.unix; | ||
| maintainers = with maintainers; [ primeos ]; | ||
| }; | ||
| } |
| @@ -1,36 +1,24 @@ | ||
| { stdenv, fetchFromGitHub, buildGoModule }: | ||
|
|
||
| buildGoModule rec { | ||
| pname = "cheat"; | ||
| version = "3.0.3"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "chrisallenlane"; | ||
| repo = "cheat"; | ||
| rev = version; | ||
| sha256 = "19w1admdcgld9vlc4fsyc5d9bi6rmwhr2x2ji43za2vjlk34hnnx"; | ||
| }; | ||
|
|
||
| subPackages = [ "cmd/cheat" ]; | ||
|
|
||
| modSha256 = "189cqnfl403f4lk7g9v68mwk93ciglqli639dk4x9091lvn5gq5q"; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| description = "Create and view interactive cheatsheets on the command-line"; | ||
| maintainers = with maintainers; [ mic92 ]; | ||
| license = with licenses; [ gpl3 mit ]; | ||
| homepage = "https://github.com/chrisallenlane/cheat"; | ||
| }; | ||
| } |
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "url": "https://hubstaff-production.s3.amazonaws.com/downloads/HubstaffClient/Builds/Release/1.5.0-4309ed45/Hubstaff-1.5.0-4309ed45.sh", | ||
| "version": "1.5.0-4309ed45", | ||
| "sha256": "1rfxizb28b8r344d18jh6shfcxz35vx8vh10c3j6zdcc998zkcr1" | ||
| } |
| @@ -29,7 +29,7 @@ in buildFHSUserEnv { | ||
|
|
||
| # Dolphin | ||
| bluez ffmpeg gettext portaudio wxGTK30 miniupnpc mbedtls lzo sfml gsm | ||
| wavpack orc nettle gmp pcre vulkan-loader | ||
|
|
||
| # DOSBox | ||
| SDL_net SDL_sound | ||
| @@ -0,0 +1,26 @@ | ||
| { lib, fetchFromGitHub, buildPythonApplication, pytest, git }: | ||
|
|
||
| buildPythonApplication rec { | ||
| pname = "mu-repo"; | ||
| version = "1.8.0"; | ||
|
|
||
| src = fetchFromGitHub { | ||
| owner = "fabioz"; | ||
| repo = pname; | ||
| rev = with lib; | ||
| "mu_repo_" + concatStringsSep "_" (splitVersion version); | ||
| sha256 = "1dxfggzbhiips0ww2s93yba9842ycp0i3x2i8vvcx0vgicv3rv6f"; | ||
| }; | ||
|
|
||
| checkInputs = [ pytest git ]; | ||
| # disable test which assumes it's a git repo | ||
| checkPhase = "py.test mu_repo --ignore=mu_repo/tests/test_checkout.py"; | ||
|
|
||
| meta = with lib; { | ||
| description = "Tool to help in dealing with multiple git repositories"; | ||
| homepage = "http://fabioz.github.io/mu-repo/"; | ||
| license = licenses.gpl3; | ||
| platforms = platforms.unix; | ||
| maintainers = with maintainers; [ sikmir ]; | ||
| }; | ||
| } |
| @@ -0,0 +1,30 @@ | ||
| { stdenv, lib, fetchhg, pkg-config, wayland, gtk3 }: | ||
|
|
||
| stdenv.mkDerivation rec { | ||
| pname = "wofi"; | ||
| version = "2019-10-28"; | ||
|
|
||
| src = fetchhg { | ||
| url = "https://hg.sr.ht/~scoopta/wofi"; | ||
| rev = "3fac708b2b541bb9927ec1b2389c4eb294e1b35b"; | ||
| sha256 = "0sp9hqm1lv9wyxj8z7vazs25nvl6yznd5vfhmwb51axwkr79s2ym"; | ||
| }; | ||
|
|
||
| nativeBuildInputs = [ pkg-config ]; | ||
| buildInputs = [ wayland gtk3 ]; | ||
|
|
||
| sourceRoot = "hg-archive/Release"; | ||
|
|
||
| installPhase = '' | ||
| mkdir -p $out/bin | ||
| cp wofi $out/bin/ | ||
| ''; | ||
|
|
||
| meta = with lib; { | ||
| description = "A launcher/menu program for wlroots based wayland compositors such as sway"; | ||
| homepage = "https://hg.sr.ht/~scoopta/wofi"; | ||
| license = licenses.gpl3; | ||
| maintainers = with maintainers; [ erictapen ]; | ||
| platforms = with platforms; linux; | ||
| }; | ||
| } |
| @@ -1,18 +1,18 @@ | ||
| # This file is autogenerated from update.sh in the same directory. | ||
| { | ||
| beta = { | ||
| sha256 = "0qklm2wyixa5xkaykbxp71xix4h8gc2w4ng33afa2nynjx07kifx"; | ||
| sha256bin64 = "1y18fcql8sv0vg8zc97f1iasx660hhgdfpr3k1rlan8jzlzdnrkk"; | ||
| version = "78.0.3904.70"; | ||
| }; | ||
| dev = { | ||
| sha256 = "01g05pqcxrk6110jfi8arkh4cq5y18n0mgbxrjd3acyirpl43s75"; | ||
| sha256bin64 = "1xm9fhqlc15wrz96f1zp00jwm1hkrjql41bbs95yvdmpdjvif34b"; | ||
| version = "79.0.3941.4"; | ||
| }; | ||
| stable = { | ||
| sha256 = "0qklm2wyixa5xkaykbxp71xix4h8gc2w4ng33afa2nynjx07kifx"; | ||
| sha256bin64 = "0vwgi8q0zs0aclvdi91g8b0knbrlaj6dwgzb0qh6c1n5blx0dmkm"; | ||
| version = "78.0.3904.70"; | ||
| }; | ||
| } |