diff --git a/nix/dev-shell.nix b/nix/dev-shell.nix index c3264ba02..f92aff013 100644 --- a/nix/dev-shell.nix +++ b/nix/dev-shell.nix @@ -1,110 +1,121 @@ { mkShell , stdenv , lib , amqp-cpp , arcanist , aws-sdk-cpp , better-prompt , boost , cargo , cmake , cmake-format , cocoapods , corrosion , cryptopp , darwin , double-conversion , folly , fmt , glog , grpc , gtest , libiconv , libuv , mariadb +, mariadb-up , nodejs-16_x , olm , openjdk8 , openssl , pkg-config , protobuf_3_15_cmake , python3 , rustc , shellcheck , sqlite , watchman , rustfmt , yarn }: mkShell { # programs which are meant to be executed should go here nativeBuildInputs = [ # generic development arcanist shellcheck # node development mariadb nodejs-16_x yarn watchman # react native python3 # native dependencies # C/CXX toolchains are already brought in with mkShell # Identity Service cargo # includes rustc rustc # allow for direct invocation of rustc rustfmt # Tunnelbroker + CMake amqp-cpp cryptopp cmake cmake-format # linting libuv pkg-config protobuf_3_15_cmake grpc ] ++ lib.optionals stdenv.isDarwin [ cocoapods # needed for ios ]; # include any libraries buildInputs buildInputs = [ # protobuf exposes both a library and a command # thus should appear in both inputs protobuf_3_15_cmake aws-sdk-cpp # tunnelbroker corrosion # tunnelbroker double-conversion # tunnelbroker glog # tunnelbroker gtest # testing services folly # cpp tools fmt # needed for folly boost # needed for folly olm # needed for CryptoTools sqlite # needed for sqlite_orm openssl # needed for grpc ] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ CoreFoundation CoreServices Security libiconv # identity service ]); JAVA_HOME = openjdk8.passthru.home; # shell commands to be ran upon entering shell shellHook = '' # Set development environment variable defaults source "${../scripts/source_development_defaults.sh}" + '' + # Darwin condition can be removed once linux services are supported + + lib.optionalString stdenv.isDarwin '' + # Start MariaDB development services + "${mariadb-up}"/bin/mariadb-up & + mariadb_pid=$! + + wait "$mariadb_pid" + '' + '' + # Provide decent bash prompt source "${better-prompt}/bin/better-prompt" echo "Welcome to Comm dev environment! :)" ''; } diff --git a/nix/mariadb-up-mac.nix b/nix/mariadb-up-mac.nix index 9baab4619..78927431b 100644 --- a/nix/mariadb-up-mac.nix +++ b/nix/mariadb-up-mac.nix @@ -1,130 +1,134 @@ { lib , gnused , openssl , mariadb , writeShellApplication , writeTextFile }: let # Use small script executed by bash to have a normal shell environment. mariadb-entrypoint = writeShellApplication { name = "mariadb-init"; text = '' MARIADB_DIR=''${XDG_DATA_HOME:-$HOME/.local/share}/MariaDB # 'exec' allows for us to replace bash process with MariaDB exec ${mariadb}/bin/mariadbd \ --socket "$MARIADB_DIR"/mysql.sock \ --datadir "$MARIADB_DIR" \ &> "$MARIADB_DIR"/logs ''; }; mariadb-version = let versions = lib.versions; in "${versions.major mariadb.version}.${versions.minor mariadb.version}"; # Small boiler-plate text file for us to write for keyserver db_config_template = writeTextFile { name = "db-config"; text = '' { "host": "localhost", "user": "comm", "password": "PASS", "database": "comm", "dbType": "mariadb${mariadb-version}" } ''; }; # writeShellApplication is a "writer helper" which # will create a shellchecked executable shell script located in $out/bin/ # This shell script will be used to allow for impure+stateful actions in writeShellApplication { name = "mariadb-up"; text = '' # "$HOME/Library/Application Support/" is the canonical path to use # on darwin for storing user data for installed applications. # However, mysql and mariadb don't quote paths in the mariadbd script, # so use XDG conventions and hope $HOME doesn't have a space. MARIADB_DATA_HOME="''${XDG_DATA_HOME:-$HOME/.local/share}/MariaDB" MARIADB_PIDFILE="$MARIADB_DATA_HOME"/mariadb.pid export MYSQL_UNIX_PORT="$MARIADB_DATA_HOME"/mysql.sock if [[ ! -d "$MARIADB_DATA_HOME"/mysql ]]; then # mysql directory should exist if MariaDB has been initialized echo "Initializing MariaDB database at $MARIADB_DATA_HOME" >&2 "${lib.getBin mariadb}/bin/mariadb-install-db" \ --datadir="$MARIADB_DATA_HOME" \ --auth-root-authentication-method=socket fi # Check if MariaDB server was already started set +e # allow for pgrep to not find matches # BSD pgrep doesn't have a "count" feature, use wc then trim whitespace mariadb_count=$(pgrep mariadbd | wc -l | xargs echo) set -e if [[ "$mariadb_count" -eq "0" ]]; then echo "Starting MariaDB server" # No MariaDB present, start our own # Launch in subshell so if the original terminal is closed, the process # will be inherited instead of also being forced closed ("${mariadb-entrypoint}/bin/mariadb-init" & echo "$!" > "$MARIADB_PIDFILE") echo "Waiting for MariaDB to come up" while [[ ! -S "$MYSQL_UNIX_PORT" ]]; do sleep 1; done elif [[ "$mariadb_count" -eq "1" ]]; then # Check if it was started by this script running_pid="$(pgrep mariadbd)" if [[ ! -f "$MARIADB_PIDFILE" ]] || \ [[ "$(cat "$MARIADB_PIDFILE")" != "$running_pid" ]]; then echo "Existing MariaDB instance found outside of nix environment" >&2 echo "Please stop existing services and attempt 'mariadb-up' again" >&2 exit 1 fi else echo "Many MariaDB instances found outside of nix environment" >&2 echo "Please stop existing services and attempt 'mariadb-up' again" >&2 exit 1 fi # Initialize comm user, database, and secrets file for MariaDB # Connecting through socket doesn't require a password userCount=$("${lib.getBin mariadb}/bin/mariadb" -u "$USER" \ -Bse "SELECT COUNT(1) FROM mysql.user WHERE user = 'comm';" ) if [[ "$userCount" -eq 0 ]]; then PASS=$("${lib.getBin openssl}/bin/openssl" rand -hex 6) echo "Creating comm user and comm database" >&2 "${lib.getBin mariadb}/bin/mariadb" -u "$USER" \ -Bse "CREATE DATABASE comm; CREATE USER comm@localhost IDENTIFIED BY '$PASS'; GRANT ALL ON "'comm.*'" TO comm@localhost;" echo "Comm user and database has been created!" >&2 # Assume this was ran from git repository PRJ_ROOT=$(git rev-parse --show-toplevel) KEYSERVER_DB_CONFIG="$PRJ_ROOT"/keyserver/secrets/db_config.json echo "Writing connection information to $KEYSERVER_DB_CONFIG" >&2 mkdir -p "$(dirname "$KEYSERVER_DB_CONFIG")" # It's very difficult to write json from bash, just copy a nix # file then use sed to subsitute cp "${db_config_template}" "$KEYSERVER_DB_CONFIG" chmod +w "$KEYSERVER_DB_CONFIG" # Nix files are read-only "${gnused}/bin/sed" -i -e "s|PASS|$PASS|g" "$KEYSERVER_DB_CONFIG" fi echo "View MariaDB Logs: tail -f $MARIADB_DATA_HOME/logs" >&2 echo "Kill MariaDB server: pkill mariadbd" >&2 + + # Explicitly exit this script so the parent shell can determine + # when it's safe to return control of terminal to user + exit 0 ''; }