ports/net-p2p/cardano-node/files/cardano_node.in
Boris Polujin 56b5f73fab net-p2p/cardano-node: Update to 8.1.2
Reviewed by: arrowd

Differential Revision: https://reviews.freebsd.org/D41169
2023-07-26 10:14:09 +03:00

338 lines
10 KiB
Bash
Executable file

#!/bin/sh
# PROVIDE: cardano_node
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# -----------------------------------------------------------------------------
#
# This script supports running multiple instances of the daemon.
# To run additional instances make a symlink to script under different name:
#
# % ln -s %%PREFIX%%/etc/rc.d/cardano_node %%PREFIX%%/etc/rc.d/SOMENAME
#
# and define corresponding SOMENAME_* variables in /etc/rc.conf
# For example, if you linked the script to cardano_node_testnet, then each
# variable listed below should read as cardano_node_testnet_enable, etc.
#
# -----------------------------------------------------------------------------
#
# Add the following lines to /etc/rc.conf to enable this service:
#
# cardano_node_enable: Set to YES to enable cardano-node.
# Default: "NO"
#
# cardano_node_jail_enable: Set to NO to disable running cardano-node in the jail.
# Default: "YES"
#
# cardano_node_home: An absolute path to the daemon home directory.
# The directory will be created if not exists.
# Default: "/var/db/cardano_node"
#
# cardano_node_net: A network name to connect to.
# Default: "mainnet"
#
# cardano_node_port: Port to listen for connections on.
# Default: "6000"
#
# Advanced settings that usually don't need to be changed for simple usage cases:
#
# cardano_node_host: Host address to bind to.
# Default: "0.0.0.0"
#
#
# cardano_node_socket: An absolute path to the daemon socket file.
# Default: "${cardano_node_home}/cardano-node.sock"
#
# cardano_node_db: An absolute path to the database directory.
# Default: "${cardano_node_home}/${cardano_node_net}-db"
#
# cardano_node_topology: An absolute or a relative to ${cardano_node_home} path
# to the topology JSON file.
# Default: "${cardano_node_net}-configs/topology.json"
#
# cardano_node_config: An absolute or a relative to ${cardano_node_home} path
# to the cardano-node config.json file.
# Default: "${cardano_node_net}-configs/config.json"
#
# cardano_node_rts_flags: GHC runtime flags to be passed between "+RTS" and "-RTS".
# See https://downloads.haskell.org/ghc/latest/docs/html/users_guide/runtime_control.html
# for the meaning of these flags.
# Default: "-N -A64m -n4m -F1.2 -qg1"
#
# cardano_node_flags: Any additional command line flags to pass to cardano-node.
# Default: ""
#
. /etc/rc.subr
# The following code snippet was taken from security/openvpn/files/openvpn.in rc script.
# service(8) does not create an authentic environment, try to guess,
# and as of 10.3-RELEASE-p0, it will not find the indented name=
# assignments below. So give it a default.
# Trailing semicolon also for service(8)'s benefit:
name="$file" ;
case "$0" in
/etc/rc*)
# during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown),
# so get the name of the script from $_file
name="$_file"
;;
*/service)
# do not use this as $0
;;
*)
name="$0"
;;
esac
# default name to "cardano_node" if guessing failed
# Trailing semicolon also for service(8)'s benefit:
name="${name:-cardano_node}" ;
name="${name##*/}"
desc="Cardano Node daemon"
rcvar="${name}_enable"
command=%%PREFIX%%/bin/cardano-node
cardano_deployment_url="https://raw.githubusercontent.com/cardano-bsd-alliance/freebsd-ports-cardano-artifacts/master/cardano-node"
cardano_config_files="config byron-genesis shelley-genesis alonzo-genesis conway-genesis topology submit-api-config"
cardano_networks="mainnet preview preprod"
start_cmd="cardano_node_start"
start_precmd="cardano_node_prestart"
stop_cmd="cardano_node_stop"
status_cmd="cardano_node_status"
reload_cmd="cardano_node_reload"
fetch_cmd="cardano_node_fetch"
extra_commands="status fetch reload"
load_rc_config $name
eval ": \${${name}_enable:=NO}"
eval ": \${${name}_jail_enable:=YES}"
eval ": \${${name}_home:=\"/var/db/cardano_node\"}"
eval ": \${${name}_net:=\"mainnet\"}"
eval ": \${${name}_host:=\"0.0.0.0\"}"
eval ": \${${name}_port:=\"6000\"}"
eval ": \${${name}_socket:=\"\${${name}_home}/cardano-node.sock\"}"
eval ": \${${name}_db:=\"\${${name}_home}/\${${name}_net}-db\"}"
eval ": \${${name}_topology:=\"\${${name}_net}-configs/topology.json\"}"
eval ": \${${name}_config:=\"\${${name}_net}-configs/config.json\"}"
eval ": \${${name}_rts_flags:=\"-N -A64m -n4m -F1.2 -qg1\"}"
eval ": \${${name}_flags:=\"\"}"
# aliases
eval "_jail_enable=\${${name}_jail_enable}"
eval "_home=\${${name}_home}"
eval "_topology=\${${name}_topology}"
eval "_config=\${${name}_config}"
eval "_socket=\${${name}_socket}"
eval "_db=\${${name}_db}"
eval "_rts_flags=\${${name}_rts_flags}"
eval "_host=\${${name}_host}"
eval "_port=\${${name}_port}"
eval "_flags=\${${name}_flags}"
jail_topology="/topology_dir/`basename ${_topology}`"
jail_config="/config_dir/`basename ${_config}`"
jail_socket="/socket/`basename ${_socket}`"
jail_args="name=${name}_jail exec.jail_user=cardano exec.system_jail_user host=inherit"
jail_command=/bin/cardano-node
jail_root="${_home}/jail"
jail_copy_resolv_conf=yes
jail_copy_services=yes
jail_copy_programs="$command /usr/sbin/nologin"
jail_mount_devfs=yes
jail_ip_inherit=yes
#TODO: daemon fails with "Network.Socket.bind: permission denied" without suid ;\
jail_prepare_inside_cmds="mkdir ./socket ;\
ln -s ${_home}/jail/${jail_socket} ${_socket} ;\
chmod +s .${jail_command}"
jail_nullfs_mounts="${_db} ${jail_root}/db rw \
${_home}/logs ${jail_root}/logs rw"
if checkyesno "_jail_enable"; then
_socket_arg="${jail_socket}"
_topology_arg="${jail_topology}"
_config_arg="${jail_config}"
_db_arg="/db"
# We need to override ${command} to make check_pidfile work correctly when
# rc.subr calls it as "check_pidfile ${pidfile} ${command}"
command=/usr/sbin/jail
else
_socket_arg="${_socket}"
_topology_arg="${_topology}"
_config_arg="${_config}"
_db_arg="${_db}"
fi
pidfile="/var/run/${name}.pid"
flags="run +RTS ${_rts_flags} -RTS \
--database-path ${_db_arg} \
--host-addr ${_host} \
--port ${_port} \
--socket-path ${_socket_arg} \
--topology ${_topology_arg} \
--config ${_config_arg} \
${_flags}"
. %%LOCALBASE%%/share/rc-subr-jail/rc.subr.jail
# realpath2 path
# Returns an absolute path to ${_home}/${path} if it exists, otherwise
# treats ${path} as absolute
realpath2()
{
local _path _realpath
_path=$1
_realpath=$(/bin/sh -c "cd ${_home} && realpath ${_path}" 2> /dev/null)
if [ $? != "0" ]
then
return 1
else
echo $_realpath
fi
}
sanity_check()
{
realpath2 ${_topology} > /dev/null
if [ $? != "0" ]
then
echo "Invalid value for ${name}_topology: missing file ${_topology}"
echo "You might want to run service ${name} onefetch to download this file into default dir"
exit 1
fi
realpath2 ${_config} > /dev/null
if [ $? != "0" ]
then
echo "Invalid value for cardano_node_config: missing file ${_config}"
echo "You might want to run service ${name} onefetch to download this file into the default dir"
exit 1
fi
return 0
}
cardano_node_prestart()
{
# Create Cardano home directory, if not exists
if [ ! -d "${_home}" ]; then
mkdir -p "${_home}"
chown cardano:cardano "${_home}"
fi
# Do the same for the logs directory
if [ ! -d "${_home}/logs" ]; then
mkdir -p "${_home}/logs"
chown cardano:cardano "${_home}/logs"
fi
# Remove the symlink to the socket file if there is no pid file
if [ -L "${_socket}" -a ! -f $pidfile ]; then
rm "${_socket}"
fi
sanity_check
}
cardano_node_start()
{
check_startmsgs && echo "Starting ${name}."
local _topo _conf
_topo=$(realpath2 ${_topology})
_conf=$(realpath2 ${_config})
jail_nullfs_mounts="$jail_nullfs_mounts $(dirname ${_topo}) ${jail_root}/topology_dir ro"
jail_nullfs_mounts="$jail_nullfs_mounts $(dirname ${_conf}) ${jail_root}/config_dir ro"
if checkyesno "_jail_enable"; then
prepare_jail $jail_root
if [ "$?" != "0" ]; then
echo "Failed to start ${name}: jail creation error"
return 1
fi
cd $_home && /bin/sh -c "/usr/sbin/daemon -p $pidfile -S -T cardano-node \
${command} -c ${jail_prepared_args} ${jail_args} command=${jail_command} ${flags}"
else
cd $_home && /usr/sbin/daemon -p $pidfile -S -T cardano-node \
${command} ${flags}
fi
}
cardano_node_stop()
{
local _topo _conf _ret
_topo=$(realpath2 ${_topology})
_conf=$(realpath2 ${_config})
jail_nullfs_mounts="$jail_nullfs_mounts $(dirname ${_topo}) ${jail_root}/topology_dir ro"
jail_nullfs_mounts="$jail_nullfs_mounts $(dirname ${_conf}) ${jail_root}/config_dir ro"
pid=$(check_pidfile "${pidfile}" "$command")
if [ -z "${pid}" ]
then
echo "${name} is not running"
_ret=1
else
echo "Stopping ${name}."
kill_jail "$pid" -INT "_jail_enable"
wait_for_pids "$pid"
_ret=0
fi
if checkyesno "_jail_enable"; then
destroy_jail $jail_root 2> /dev/null
fi
rm -rf ${_socket}
return $_ret
}
cardano_node_status()
{
pid=$(check_pidfile "${pidfile}" "$command")
if [ -z "${pid}" ]
then
echo "${name} is not running"
return 1
else
echo ${name} is running as pid $pid
fi
}
cardano_node_reload()
{
pid=$(check_pidfile "${pidfile}" "$command")
if [ -z "${pid}" ]
then
echo "${name} is not running"
return 1
else
kill_jail "$pid" -HUP "_jail_enable"
fi
}
cardano_node_fetch()
{
for net in ${cardano_networks}
do
echo "===> Fetching configuration files for ${net}"
mkdir -p "${_home}/${net}-configs"
mkdir -p "${_home}/${net}-db"
/usr/bin/apply "/usr/bin/fetch -a -o \
${_home}/${net}-configs ${cardano_deployment_url}/${net}-configs/%1.json" $cardano_config_files
chown -R cardano:cardano "${_home}/${net}-configs"
chown -R cardano:cardano "${_home}/${net}-db"
done
}
run_rc_command "$1"