diff --git a/nix/dev-shell.nix b/nix/dev-shell.nix index cd0f81665..f964c3f50 100644 --- a/nix/dev-shell.nix +++ b/nix/dev-shell.nix @@ -1,66 +1,70 @@ { mkShell , stdenv , lib , amqp-cpp , arcanist , cargo , cmake , cryptopp , darwin , grpc , libuv , nodejs-16_x , pkg-config , protobuf_3_15_cmake , python2 , python3 , watchman , rustfmt , yarn }: mkShell { # programs which are meant to be executed should go here nativeBuildInputs = [ # generic development arcanist # node development nodejs-16_x yarn watchman # react native python2 python3 # native dependencies # C/CXX toolchains are already brought in with mkShell # Identity Service cargo # includes rustc rustfmt # Tunnelbroker + CMake amqp-cpp cryptopp cmake libuv pkg-config protobuf_3_15_cmake grpc ]; # include any libraries buildInputs buildInputs = [ protobuf_3_15_cmake # exposes both a library and a command, thus should appear in both inputs ] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ CoreFoundation CoreServices Security ]); # shell commands to be ran upon entering shell shellHook = '' + if [[ "$OSTYPE" == 'linux'* ]]; then + export MYSQL_UNIX_PORT=''${XDG_RUNTIME_DIR:-/run/user/$UID}/mysql-socket/mysql.sock + fi + echo "Welcome to Comm dev environment! :)" ''; } diff --git a/nix/mysql-down-linux.nix b/nix/mysql-down-linux.nix new file mode 100644 index 000000000..3173bf920 --- /dev/null +++ b/nix/mysql-down-linux.nix @@ -0,0 +1,15 @@ +{ lib +, writeShellScriptBin +}: + +# writeShellScriptBin is a "writer helper" which +# will create an executable shell script located in $out/bin/ +# This shell script will be used to allow for impure+stateful actions +writeShellScriptBin "mysql-down" '' + set -euo pipefail + + echo "Attempting to stop user MySQL server instance" >&2 + systemctl stop --user comm-mysql + + echo "Succesfully killed" >&2 +'' diff --git a/nix/mysql-up-linux.nix b/nix/mysql-up-linux.nix new file mode 100644 index 000000000..9f35ec229 --- /dev/null +++ b/nix/mysql-up-linux.nix @@ -0,0 +1,79 @@ +{ lib +, writeShellScriptBin +, writeTextFile +, mysql57 +}: + +let + # This will create a comm-mysql.service meant to be consumed by systemd as a user unit file + # Settings: + # port = 3306 + # datadir = ~/.cache/mysql + # socket = /run/user/1000/mysql-socket/mysql.sock + mysql-user-service-unit = writeTextFile { + name = "comm-mysql"; + text = '' + [Unit] + Description=MySQL Server + + [Service] + ExecStart=${lib.getBin mysql57}/bin/mysqld --port 3306 --datadir=%h/.cache/mysql --socket=%t/mysql-socket/mysql.sock + Restart=on-failure + ProtectHome=read-only + ProtectSystem=strict + PrivateTmp=true + + [Install] + WantedBy=default.target + ''; + destination = "/comm-mysql.service"; + + }; +in + +# writeShellScriptBin is a "writer helper" which +# will create an executable shell script located in $out/bin/ +# This shell script will be used to allow for impure+stateful actions +writeShellScriptBin "mysql-up" '' + set -euo pipefail + + mkdir -p ''${XDG_CACHE_HOME:-$HOME/.cache}/mysql ''${XDG_RUNTIME_DIR:-/run/user/$UID}/mysql-socket + + if [[ ! -d ''${XDG_CACHE_HOME:-$HOME/.cache}/mysql/mysql ]]; then + # ~/.cache/mysql/mysql should exist if mysql has been initialized + echo "Initializing MySQL database at ''${XDG_CACHE_HOME:-$HOME/.cache}/mysql" >&2 + ${lib.getBin mysql57}/bin/mysqld --initialize-insecure --datadir=''${XDG_CACHE_HOME:-$HOME/.cache}/mysql + fi + + needsReload= + + # check if service was installed + if [[ ! -r "''${XDG_CONFIG_DIR:-$HOME/.config}/systemd/user/comm-mysql.service" ]]; then + needsReload=1 + fi + + # Install the service unit file into the default systemd location + ln -sf ${mysql-user-service-unit}/comm-mysql.service ''${XDG_CONFIG_DIR:-$HOME/.config}/systemd/user/comm-mysql.service + + # Conditionally enable unit file + [[ -n "$needsReload" ]] && systemctl --user daemon-reload + + # Start mysql + echo "Starting MySQL server as user service: comm-mysql" + systemctl start --user comm-mysql.service + + # Initialize Comm user and database for MySQL + userCount=$(mysql -u root --password="" -Bse "SELECT COUNT(1) FROM mysql.user WHERE user = 'comm';") + if [[ "''$userCount" -eq 0 ]]; then + echo "Creating comm user and database for mysql" >&2 + echo -n "Please enter a password for new comm user: " >&2 + read -rs password + + mysql -u root --password="" -e"CREATE DATABASE comm; CREATE USER comm@localhost IDENTIFIED BY '"$password"'; GRANT ALL ON comm.* TO comm@localhost;" + echo "Comm user and database has been created!" >&2 + fi + + echo "" >&2 + echo "View MySQL Logs: journalctl -f --user-unit comm-mysql" >&2 + echo "Kill MySQL server: nix run .#mysql-down" >&2 +'' diff --git a/nix/overlay.nix b/nix/overlay.nix index 7697939c7..376f79f69 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -1,19 +1,23 @@ # An overlay allows for a package set to be extended with new or modified packages # `final` refers to the package set with all overlays applied. # This allows for added or modified packages to be referenced with # all relevant changes final: # `prev` refers to the previous package set before this current overlay is applied. # This is cheaper for nix to evaluate, thus should be prefered over final when possible. prev: { # add packages meant for just this repository amqp-cpp = prev.callPackage ./amqp-cpp.nix { }; protobuf_3_15_cmake = prev.callPackage ./protobuf_3_15.nix { }; devShell = final.callPackage ./dev-shell.nix { }; + + mysql-down = prev.callPackage ./mysql-down-linux.nix { }; + + mysql-up = prev.callPackage ./mysql-up-linux.nix { }; }