From 961a1b5190ecee4d65e9959a97ad96068e5efa67 Mon Sep 17 00:00:00 2001 From: Hsing-Wang Liao Date: Sun, 13 Aug 2017 13:39:44 +0800 Subject: [PATCH] aria2: Rewrite init script * Add aria2 user and group. * Use procd to start service. * Add more supported options. Compatible with previous version. Signed-off-by: Hsing-Wang Liao --- net/aria2/Makefile | 3 +- net/aria2/files/aria2.conf | 27 ++- net/aria2/files/aria2.init | 396 +++++++++++++++++++++++++++++-------- 3 files changed, 342 insertions(+), 84 deletions(-) diff --git a/net/aria2/Makefile b/net/aria2/Makefile index 7dd55b0d9..c06c5fc2e 100644 --- a/net/aria2/Makefile +++ b/net/aria2/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=aria2 PKG_VERSION:=1.32.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/ @@ -44,6 +44,7 @@ define Package/aria2 TITLE:=lightweight download utility URL:=https://aria2.github.io/ DEPENDS:=+zlib +libstdcpp +ARIA2_SFTP:libssh2 +ARIA2_ASYNC_DNS:libcares +ARIA2_COOKIE:libsqlite3 +ARIA2_LIBXML2:libxml2 +ARIA2_EXPAT:libexpat +ARIA2_OPENSSL:libopenssl +ARIA2_GNUTLS:libgnutls + USERID:=aria2=6800:aria2=6800 endef define Package/aria2/description diff --git a/net/aria2/files/aria2.conf b/net/aria2/files/aria2.conf index e6d76171f..108a30e01 100644 --- a/net/aria2/files/aria2.conf +++ b/net/aria2/files/aria2.conf @@ -1,10 +1,31 @@ +# You can use most aria2 command-line options, replace '-' with '_'. +# eg. 'rpc-secret' ==> 'rpc_secret' +# +# We do not support all options at this time. But you can add any option +# with 'list extra_settings'. +# +# You can also add new config sections to define multi instance. +# config aria2 'main' option enabled '0' - option file_allocation 'none' + option user 'aria2' + option dir '/mnt/sda1/aria2' + option config_dir '/var/etc/aria2' option bt_enable_lpd 'true' option enable_dht 'true' option follow_torrent 'true' - option user 'root' - option dir '/mnt/sda1/aria2' + option file_allocation 'none' option save_session_interval '30' + + # Add addition Headers here. + # eg. list header 'Content-Encoding: gzip' + list header '' + + # Add BT trackers here. + # eg. list bt_tracker 'http://tracker.example.com/announce' + list bt_tracker '' + + # Add extra settings here. + # eg. list extra_settings 'option=value' + list extra_settings '' diff --git a/net/aria2/files/aria2.init b/net/aria2/files/aria2.init index d6bcda4ab..ca230f854 100755 --- a/net/aria2/files/aria2.init +++ b/net/aria2/files/aria2.init @@ -1,112 +1,348 @@ #!/bin/sh /etc/rc.common -# Copyright (C) 2014-2016 nanpuyue -# Copyright (C) 2016 kuoruan +# Copyright (C) 2016-2017 Hsing-wang Liao +# Licensed to the public under the Apache License 2.0. START=99 -SERVICE_WRITE_PID=1 -SERVICE_DAEMONIZE=1 - - -append_params() { - local p; local v; local s="$1"; shift - for p in $*; do - config_get v "$s" "$p" - [ -n "$v" ] && ( - p=$(echo "$p" | sed -e 's|_|-|g'); - echo "$p=$v" >> $config_file - ) +USE_PROCD=1 + +NAME=aria2 +PROG=/usr/bin/aria2c + +_info() { + logger -p daemon.info -t "$NAME" "$*" +} + +_err() { + logger -p daemon.err -t "$NAME" "$*" +} + +_make_dir() { + local d + for d in "$@"; do + if [ ! -d "$d" ]; then + mkdir -p "$d" 2>/dev/null || return 1 + fi done + + return 0 } -section_enabled() { - local result - config_get_bool result "$1" 'enabled' 0 - [ $result -eq 1 ] +_create_file() { + touch "$@" 2>/dev/null } -option_disabled() { - local result - config_get_bool result "$1" "$2" 1 - [ $result -eq 0 ] +_change_owner() { + local u="$1"; shift + + local d + for d in "$@"; do + if [ -f "$d" ]; then + chown "$u" "$d" 2>/dev/null || return 1 + elif [ -d "$d" ]; then + chown -R "$u" "$d" 2>/dev/null || return 1 + fi + done + + return 0 } -start_instance() { +_change_file_mode() { + local mod="$1"; shift + chmod "$mod" "$@" 2>/dev/null +} + +_reset_dir_mode() { + local d + for d in "$@"; do + if [ -d "$d" ]; then + find "$d" -type d -exec chmod 755 {} \; 2>/dev/null + find "$d" -type f -exec chmod 644 {} \; 2>/dev/null + fi + done +} + +append_options() { + local o; local v + for o in "$@"; do + v="$(eval echo "\$$o")" + [ -n "$v" ] && \ + echo "${o//_/-}=$v" >>"$config_file_tmp" + done +} + +append_setting() { local s="$1" - local user + [ -n "$s" ] && \ + echo "$s" >>"$config_file_tmp" +} + +append_header() { + local h="$1" + [ -n "$h" ] && \ + echo "header=\"${h}\"" >>"$config_file_tmp" +} + +aria2_validate() { + uci_validate_section "$NAME" aria2 "$1" \ + 'enabled:bool:0' \ + 'enable_logging:bool' \ + 'enable_proxy:bool' \ + 'config_dir:string:/var/etc/aria2' \ + 'user:string' \ + 'all_proxy:string' \ + 'all_proxy_passwd:string' \ + 'all_proxy_user:string' \ + 'auto_save_interval:range(0,600)' \ + 'bt_enable_lpd:or("true","false")' \ + 'bt_max_open_files:uinteger' \ + 'bt_max_peers:uinteger' \ + 'bt_remove_unselected_file:or("true","false")' \ + 'bt_request_peer_speed_limit:string' \ + 'bt_save_metadata:or("true","false")' \ + 'bt_seed_unverified:or("true","false")' \ + 'bt_stop_timeout:uinteger' \ + 'bt_tracker:list(string)' \ + 'ca_certificate:file' \ + 'certificate:file' \ + 'check_certificate:or("true","false"):true' \ + 'connect_timeout:uinteger' \ + 'dht_listen_port:string' \ + 'dir:string' \ + 'disable_ipv6:or("true","false")' \ + 'disk_cache:string' \ + 'enable_dht:or("true","false"):true' \ + 'enable_dht6:or("true","false")' \ + 'enable_peer_exchange:("true","false")' \ + 'event_poll:("epoll","kqueue","port","poll","select")' \ + 'file_allocation:or("none","prealloc","trunc","falloc")' \ + 'follow_torrent:or("true","false","mem")' \ + 'force_save:or("true","false")' \ + 'http_accept_gzip:or("true","false")' \ + 'http_no_cache:or("true","false")' \ + 'listen_port:string' \ + 'log:string' \ + 'log_level:or("debug","info","notice","warn","error")' \ + 'lowest_speed_limit:string' \ + 'max_concurrent_downloads:uinteger' \ + 'max_connection_per_server:uinteger' \ + 'max_download_limit:string' \ + 'max_overall_download_limit:string' \ + 'max_overall_upload_limit:string' \ + 'max_tries:uinteger' \ + 'max_upload_limit:string' \ + 'min_split_size:string' \ + 'pause:or("true","false")' \ + 'pause_metadata:or("true","false")' \ + 'peer_id_prefix:string' \ + 'private_key:file' \ + 'retry_wait:uinteger' \ + 'rpc_auth_method:or("none","user_pass","token")' \ + 'rpc_certificate:file' \ + 'rpc_listen_port:range(1024,65535)' \ + 'rpc_passwd:string' \ + 'rpc_private_key:file' \ + 'rpc_secret:string' \ + 'rpc_secure:or("true","false")' \ + 'rpc_user:string' \ + 'save_session_interval:uinteger' \ + 'seed_ratio:ufloat' \ + 'seed_time:ufloat' \ + 'split:uinteger' \ + 'timeout:uinteger' \ + 'user_agent:string' +} - section_enabled "$s" || return 1 +aria2_start() { + local section="$1" + aria2_validate "$section" || { _err "Validation failed."; return 1; } - config_get config_dir "$s" 'config_dir' '/var/etc/aria2' - config_get dir "$s" 'dir' - config_get user "$s" 'user' + [ "$enabled" = "1" ] || { _info "Instance \"${section}\" disabled."; return 1; } + [ -n "$dir" ] || { _err "Please set downlod dir."; return 1; } + [ -d "$dir" ] || { _err "Please create downlod dir first."; return 1; } - config_file="$config_dir/aria2.conf" - session_file="$config_dir/aria2.session" - dht_file="$config_dir/dht.dat" - log_file="$config_dir/aria2.log" + config_file="${config_dir}/${NAME}.conf.${section}" + config_file_tmp="${config_dir}/${NAME}.conf.tmp" + session_file="${config_dir}/${NAME}.session.${section}" - [ -d "$config_dir" ] || { - mkdir -m 0755 -p "$config_dir" - touch "$config_file" + _make_dir "$config_dir" || { + _err "Can't create config dir: ${config_dir}" + return 1 } - [ -d "$dir" ] || { - mkdir -m 0755 -p "$dir" # create download dir - touch "$dir" + _create_file "$session_file" "$config_file" "$config_file_tmp" || { + _err "Can't create files: ${session_file}, ${config_file}, ${config_file_tmp}" + return 1 } - touch "$session_file" # create session file + # create tmp file + cat >"$config_file_tmp" <<-EOF + # Auto generated file, changes to this file will lost. + EOF + + append_setting "dir=${dir}" + append_setting "enable-rpc=true" + append_setting "rpc-allow-origin-all=true" + append_setting "rpc-listen-all=true" + append_setting "quiet=true" + append_setting "continue=true" + append_setting "input-file=${session_file}" + append_setting "save-session=${session_file}" + + if [ -z "$enable_logging" ]; then + append_options "log" "log_level" + elif [ "$enable_logging" = "1" ]; then + log=${log:-"/var/log/aria2.log"} + + local log_dir + log_dir="$(dirname "$log")" + + _make_dir "$log_dir" || { + _err "Can't create log dir: ${log_dir}" + return 1 + } - echo -e "enable-rpc=true\nrpc-allow-origin-all=true\nrpc-listen-all=true\nquiet=true" > $config_file - echo -e "continue=true\ninput-file=$session_file\nsave-session=$session_file" >> $config_file + # create or clear log file + echo >"$log" - option_disabled "$s" 'enable_dht' || echo "dht-file-path=$dht_file" >> $config_file - option_disabled "$s" 'enable_log' || { - [ -f "$log_file" ] && echo > $log_file # if log file exist, clear it - echo -e "log=$log_file" >> $config_file - } + append_setting "log=${log}" + append_options "log_level" + fi + + if [ -z "$enable_proxy" ] || [ "$enable_proxy" = "1" ]; then + append_options "all_proxy" "all_proxy_user" "all_proxy_passwd" + fi - # if user is set, change dir owner - [ -z "$user" ] || { - chown -R $user:$user $config_dir - chown -R $user:$user $dir + unset_auth_method() { + uci -q batch <<-EOF + set ${NAME}.${section}.rpc_auth_method="" + commit $NAME + EOF } - append_params "$s" \ - file_allocation bt_enable_lpd enable_dht rpc_user rpc_passwd rpc_listen_port dir bt_tracker disk_cache \ - max_overall_download_limit max_overall_upload_limit max_download_limit max_upload_limit max_concurrent_downloads \ - max_connection_per_server min_split_size split save_session_interval follow_torrent listen_port bt_max_peers \ - peer_id_prefix user_agent rpc_secret log_level - - config_list_foreach "$s" extra_settings append_extrasettings - - SERVICE_UID="$user" \ - service_start /usr/bin/aria2c --conf-path="$config_file" # start service -} + if [ -z "$rpc_auth_method" ]; then + if [ -n "$rpc_secret" ]; then + append_setting "rpc-secret=${rpc_secret}" + elif [ -n "$rpc_user" ]; then + append_setting "rpc-user=${rpc_user}" + append_setting "rcp-passwd=${rcp-passwd}" + else + _info "It is recommand to set RPC secret." + fi + elif [ "$rpc_auth_method" = "token" ]; then + if [ -n "$rpc_secret" ]; then + append_setting "rpc-secret=${rpc_secret}" + else + unset_auth_method + fi + elif [ "$rpc_auth_method" = "user_pass" ]; then + if [ -n "$rcp_user" ]; then + append_setting "rpc-user=${rpc_user}" + append_setting "rcp-passwd=${rcp-passwd}" + else + _info "Please set RPC user." + unset_auth_method + fi + fi -append_extrasettings() { - echo "$1" >> $config_file -} + if [ ."$rpc_secure" = ."true" ] && [ -n "$rpc_certificate" ]; then + append_setting "rpc-secure=true" + append_options "rpc_certificate" "rpc_private_key" + fi -start() { - logger -t ARIA2C 'Starting aria2c service' - config_load 'aria2' - config_foreach start_instance 'aria2' - return 0 -} + if [ ."$check_certificate" = ."true" ]; then + append_setting "check-certificate=true" + append_options "ca_certificate" + fi -stop() { - if [ -n "`pidof aria2c`" ]; then - logger -t ARIA2C 'Shutting down aria2c service' - service_stop /usr/bin/aria2c + if [ ."$enable_dht" = ."true" ]; then + dht_file="${config_dir}/dht.dat.${section}" + _create_file "$dht_file" || { + _err "Can't create DHT file: ${dht_file}" + return 1 + } + + append_setting "enable-dht=true" + append_setting "dht-file-path=${dht_file}" fi - return 0 + + if [ ."$enable_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then + dht6_file="${config_dir}/dht6.dat.${section}" + _create_file "$dht6_file" || { + _err "Can't create DHT6 file: ${dht6_file}" + return 1 + } + + append_setting "enable-dht6=true" + append_setting "dht-file-path6=${dht6_file}" + fi + + if [ -n "$bt_tracker" ]; then + local bt_tracker_list; local t + for t in $bt_tracker; do + if [ -z "$bt_tracker_list" ]; then + bt_tracker_list="$t" + else + bt_tracker_list="${bt_tracker_list},${t}" + fi + done + + append_setting "bt-tracker=${bt_tracker_list}" + fi + + append_options "auto_save_interval" "bt_enable_lpd" "bt_max_open_files" "bt_max_peers" \ + "bt_remove_unselected_file" "bt_request_peer_speed_limit" "bt_save_metadata" "bt_seed_unverified" \ + "bt_stop_timeout" "certificate" "connect_timeout" "dht_listen_port" "disable_ipv6" "disk_cache" \ + "enable_peer_exchange" "event_poll" "file_allocation" "follow_torrent" "force_save" "http_accept_gzip" \ + "http_no_cache" "listen_port" "lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" \ + "max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \ + "max_upload_limit" "min_split_size" "pause" "pause_metadata" "peer_id_prefix" "private_key" \ + "retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "split" "timeout" \ + "user_agent" + + config_list_foreach "$section" "header" append_header + config_list_foreach "$section" "extra_settings" append_setting + + sed '/^$/d' "$config_file_tmp" >"$config_file" + rm -f "$config_file_tmp" + + _reset_dir_mode "$config_dir" + _change_file_mode 600 "$config_file" + + if [ -n "$user" ]; then + if ( user_exists "$user" && _change_owner "$user" "$config_dir" "$log" ); then + _info "Aria2 will run with uer '${user}'." + if [ "$user" != "root" ]; then + _info "Please make sure user '${user}' has write access to downlod dir: ${dir}" + fi + else + _info "Set run user to '${user}' failed, default user will be used." + user= + fi + fi + + procd_open_instance "${NAME}.${section}" + procd_set_param command "$PROG" + procd_append_param command --conf-path="${config_file}" + + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_set_param file "$config_file" + [ -n "$user" ] && \ + procd_set_param user "$user" + + procd_add_jail "${NAME}.${section}" log + procd_add_jail_mount "$config_file" + procd_add_jail_mount_rw "$dir" "$config_dir" "$log" + procd_close_instance } -restart() { - logger -t ARIA2C 'Restarting aria2c service' - stop - sleep 2 # give time to shutdown - start +service_triggers() { + procd_add_reload_trigger "$NAME" } +start_service() { + config_load "$NAME" + config_foreach aria2_start "aria2" +}