mirror of
https://git.freebsd.org/ports.git
synced 2025-07-03 18:39:16 -04:00
338 lines
10 KiB
Bash
Executable file
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"
|