Skip to content

Commit

Permalink
cassandra: init service (#116)
Browse files Browse the repository at this point in the history
* cassandra: init service

* cassandra: add cassandra/conf files

* cassandra_test: change package to cassandra_4

* update readiness_probe

* update cassandra_test

* cassandra: add doc

* cassandra_4 doesn't require python-2

---------

Co-authored-by: shivaraj-bh <[email protected]>
  • Loading branch information
conscious-puppet and shivaraj-bh authored Mar 3, 2024
1 parent 5e48c5a commit 6aeb0ea
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
31 changes: 31 additions & 0 deletions doc/cassandra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Cassandra

[Cassandra] is a free and open-source, distributed, wide-column store, NoSQL database management system designed to handle large amounts of data across many commodity servers, providing high availability with no single point of failure.

[Cassandra]: https://cassandra.apache.org/_/index.html

## Getting Started

```nix
# In `perSystem.process-compose.<name>`
{
services.cassandra."cass1".enable = true;
}
```

{#tips}
## Tips & Tricks

{#change-port}
### Change the default port

By default, the Cassandra server is started on port `9042`. To change the port, we can use the following config:

```nix
{
services.cassandra."cass1" = {
enable = true;
nativeTransportPort = 9043;
};
}
```
1 change: 1 addition & 0 deletions doc/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ short-title: Services
- [x] [[grafana]]#
- [X] [[prometheus]]#
- [X] [[pgadmin]]#
- [X] [[cassandra]]#
- [ ] ...

[gh]: https://github.com/juspay/services-flake
169 changes: 169 additions & 0 deletions nix/cassandra.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Based on https://github.com/cachix/devenv/blob/fa9a708e240c6174f9fc4c6eefbc6a89ce01c350/src/modules/services/cassandra.nix
{ pkgs, lib, name, config, ... }:
let
inherit (lib) types;
yamlFormat = pkgs.formats.yaml { };
in
{
options = {
enable = lib.mkEnableOption name;

package = lib.mkPackageOption pkgs "cassandra" { };

dataDir = lib.mkOption {
type = types.str;
default = "./data/${name}";
description = "The cassandra data directory";
};

listenAddress = lib.mkOption {
type = types.str;
description = "Listen address";
default = "127.0.0.1";
example = "127.0.0.1";
};

nativeTransportPort = lib.mkOption {
type = types.port;
description = "port for the CQL native transport to listen for clients on";
default = 9042;
};

seedAddresses = lib.mkOption {
type = types.listOf types.str;
default = [ "127.0.0.1" ];
description = "The addresses of hosts designated as contact points of the cluster";
};

clusterName = lib.mkOption {
type = types.str;
default = "Test Cluster";
description = "The name of the cluster";
};

allowClients = lib.mkOption {
type = types.bool;
default = true;
description = ''
Enables or disables the native transport server (CQL binary protocol)
'';
};

extraConfig = lib.mkOption {
type = yamlFormat.type;
default = { };
example =
{
commitlog_sync_batch_window_in_ms = 3;
};
description = ''
Extra options to be merged into `cassandra.yaml` as nix attribute set.
'';
};

jvmOpts = lib.mkOption {
type = types.listOf types.str;
default = [ ];
description = "Options to pass to the JVM through the JVM_OPTS environment variable";
};

defaultExtraConfig = lib.mkOption {
type = yamlFormat.type;
internal = true;
readOnly = true;
default = {
start_native_transport = config.allowClients;
listen_address = config.listenAddress;
native_transport_port = config.nativeTransportPort;
commitlog_sync = "batch";
commitlog_sync_batch_window_in_ms = 2;
cluster_name = config.clusterName;
partitioner = "org.apache.cassandra.dht.Murmur3Partitioner";
endpoint_snitch = "SimpleSnitch";
data_file_directories = [ "${config.dataDir}/data" ];
commitlog_directory = "${config.dataDir}/commitlog";
saved_caches_directory = "${config.dataDir}/saved_caches";
hints_directory = "${config.dataDir}/hints";
seed_provider = [
{
class_name = "org.apache.cassandra.locator.SimpleSeedProvider";
parameters = [{ seeds = lib.concatStringsSep "," config.seedAddresses; }];
}
];
};
};

outputs.settings = lib.mkOption {
type = types.deferredModule;
internal = true;
readOnly = true;
default = {
processes = {
"${name}" =
let
cassandraConfig = pkgs.stdenv.mkDerivation {
name = "cassandra-config";
cassandraYaml = yamlFormat.generate "cassandra.yaml" (
lib.recursiveUpdate config.defaultExtraConfig config.extraConfig
);
buildCommand = ''
mkdir -p $out
for d in ${config.package}/conf/*; do ln -s "$d" $out/; done
rm -rf $out/cassandra.y*ml
ln -s "$cassandraYaml" "$out/cassandra.yaml"
rm -rf $out/cassandra-env.sh
cat ${config.package}/conf/cassandra-env.sh > $out/cassandra-env.sh
LOCAL_JVM_OPTS="${lib.concatStringsSep " " config.jvmOpts}"
echo "JVM_OPTS=\"\$JVM_OPTS $LOCAL_JVM_OPTS\"" >> $out/cassandra-env.sh
'';
};

startScript = pkgs.writeShellScriptBin "start-cassandra" ''
set -euo pipefail
DATA_DIR="$(readlink -m ${config.dataDir})"
if [[ ! -d "$DATA_DIR" ]]; then
mkdir -p "$DATA_DIR"
fi
CASSANDRA_CONF="${cassandraConfig}"
export CASSANDRA_CONF
CASSANDRA_LOG_DIR="$DATA_DIR/log/"
mkdir -p "$CASSANDRA_LOG_DIR"
export CASSANDRA_LOG_DIR
CASSANDRA_HOME="${config.package}"
export CASSANDRA_HOME
CLASSPATH="${config.package}/lib"
export CLASSPATH
export LOCAL_JMX="yes"
exec ${config.package}/bin/cassandra -f
'';
in
{
command = startScript;

readiness_probe = {
exec.command = ''
echo 'show version;' | CQLSH_HOST=${config.listenAddress} CQLSH_PORT=${toString config.nativeTransportPort} ${config.package}/bin/cqlsh
'';
initial_delay_seconds = 2;
period_seconds = 10;
timeout_seconds = 4;
success_threshold = 1;
failure_threshold = 5;
};
namespace = name;

# https://github.com/F1bonacc1/process-compose#-auto-restart-if-not-healthy
availability.restart = "on_failure";
};
};
};
};
};
}
27 changes: 27 additions & 0 deletions nix/cassandra_test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{ pkgs, config, ... }: {
services.cassandra."cass1" = {
enable = true;
# support for aarch64-darwin was added in cassandra-4
# https://github.com/apache/cassandra/blob/a87055d56a33a9b17606f14535f48eb461965b82/CHANGES.txt#L192
package = pkgs.cassandra_4;
};

settings.processes.test =
let
cfg = config.services.cassandra."cass1";
in
{
command = pkgs.writeShellApplication {
runtimeInputs = [ cfg.package ];
text = ''
echo "show version;" | cqlsh
echo "create keyspace test with replication = {'class': 'SimpleStrategy', 'replication_factor': 1};" | cqlsh
echo "CREATE TABLE test.test_table(id int PRIMARY KEY, name text);" | cqlsh
echo "insert into test.test_table (id, name) VALUES (1, 'hello');" | cqlsh
echo "select * from test.test_table;" | cqlsh | grep hello
'';
name = "cassandra-test";
};
depends_on."cass1".condition = "process_healthy";
};
}
1 change: 1 addition & 0 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ in
./grafana.nix
./prometheus.nix
./pgadmin.nix
./cassandra.nix
];
}
1 change: 1 addition & 0 deletions test/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"${inputs.services-flake}/nix/grafana_test.nix"
"${inputs.services-flake}/nix/prometheus_test.nix"
"${inputs.services-flake}/nix/pgadmin_test.nix"
"${inputs.services-flake}/nix/cassandra_test.nix"
]);
};
};
Expand Down

0 comments on commit 6aeb0ea

Please sign in to comment.