diff --git a/cross/adminer/patches/001-not-use-pgsql-extension.patch b/cross/adminer/patches/001-not-use-pgsql-extension.patch index 6fc31bf9e47..632836eed7a 100644 --- a/cross/adminer/patches/001-not-use-pgsql-extension.patch +++ b/cross/adminer/patches/001-not-use-pgsql-extension.patch @@ -1,15 +1,15 @@ # See https://github.com/SynoCommunity/spksrc/issues/2662 # Remove the extension pgsql because the extension pgsql does not work with the PostgreSQL server from DSM. The Extension pdo_pgsql works perfectly. ---- adminer/drivers/pgsql.inc.php.org 2020-01-31 10:23:04.000000000 +0000 -+++ adminer/drivers/pgsql.inc.php 2020-02-23 16:59:43.482304615 +0000 -@@ -4,146 +4,8 @@ +--- adminer/drivers/pgsql.inc.php.orig 2021-05-14 05:39:59.000000000 +0000 ++++ adminer/drivers/pgsql.inc.php 2023-10-07 23:07:43.616901493 +0000 +@@ -3,146 +3,7 @@ + if (isset($_GET["pgsql"])) { - $possible_drivers = array("PgSQL", "PDO_PgSQL"); define("DRIVER", "pgsql"); - if (extension_loaded("pgsql")) { - class Min_DB { - var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout; - +- - function _error($errno, $error) { - if (ini_bool("html_errors")) { - $error = html_entity_decode(strip_tags($error)); @@ -43,7 +43,7 @@ - } - - function value($val, $field) { -- return ($field["type"] == "bytea" ? pg_unescape_bytea($val) : $val); +- return ($field["type"] == "bytea" && $val !== null ? pg_unescape_bytea($val) : $val); - } - - function quoteBinary($string) { diff --git a/cross/cops/Makefile b/cross/cops/Makefile index bbbf34de200..2b0db810421 100644 --- a/cross/cops/Makefile +++ b/cross/cops/Makefile @@ -10,7 +10,7 @@ DEPENDS = HOMEPAGE = https://blog.slucas.fr/en/oss/calibre-opds-php-server COMMENT = Calibre OPDS and HTML PHP Server : light alternative to Calibre content server / Calibre2OPDS. -LICENSE = GPL +LICENSE = GPLv2 INSTALL_TARGET = cops_install diff --git a/mk/spksrc.icon.mk b/mk/spksrc.icon.mk index 3cdbb6546fd..ac48bb29c7c 100644 --- a/mk/spksrc.icon.mk +++ b/mk/spksrc.icon.mk @@ -14,7 +14,9 @@ ICON_COOKIE = $(WORK_DIR)/.$(COOKIE_PREFIX)icon_done # Icons are only needed with "DSM UI configuration" (see spksrc.service.mk) ifneq ($(strip $(DSM_UI_DIR)),) ifneq ($(strip $(SPK_ICON)),) -ifneq ($(or $(strip $(SERVICE_PORT)), $(strip $(ADMIN_URL))),) +ifneq ($(strip $(DSM_UI_CONFIG)),) +ICON_DIR = $(STAGING_DIR)/$(DSM_UI_DIR)/images +else ifneq ($(or $(strip $(SERVICE_PORT)), $(strip $(ADMIN_URL))),) ifeq ($(strip $(NO_SERVICE_SHORTCUT)),) ICON_DIR = $(STAGING_DIR)/$(DSM_UI_DIR)/images endif diff --git a/mk/spksrc.service.installer.dsm5 b/mk/spksrc.service.installer.dsm5 index 410c894be3c..b3509fb8eff 100644 --- a/mk/spksrc.service.installer.dsm5 +++ b/mk/spksrc.service.installer.dsm5 @@ -60,7 +60,7 @@ fi # Load (wizard) variables stored by postinst -call_func "load_variables_from_file" ${INST_VARIABLES} +load_variables_from_file ${INST_VARIABLES} # init variables either from ${INST_VARIABLES}, from package or from wizard call_func "initialize_variables" @@ -140,9 +140,9 @@ set_syno_permissions () # Ensure directory resides in /volumeX before setting GROUP permissions if [ "$(echo ${VOLUME} | cut -c2-7)" = "volume" ]; then # Set read/write permissions for GROUP for folder and subfolders - if [ ! "$(synoacltool -get \"${DIRNAME}\"| grep \"group:${GROUP}:allow:rwxpdDaARWcC-:fd--\")" ]; then + if [ ! "$(synoacltool -get ${DIRNAME} | grep ""group:${GROUP}:allow:rwxpdDaARWcC-:fd--"")" ]; then # First Unix permissions, but only if it's in Linux mode - if [ "$(synoacltool -get \"${DIRNAME}\"| grep \"Linux mode\")" ]; then + if [ "$(synoacltool -get ${DIRNAME} | grep -i 'Linux mode')" ]; then set_unix_permissions "${DIRNAME}" # If it is linux mode (due to old package) we need to add "administrators"-group, # otherwise the folder is not accessible from File Station anymore! @@ -157,9 +157,9 @@ set_syno_permissions () # Walk up the tree and set traverse execute permissions for GROUP up to VOLUME while [ "${DIRNAME}" != "${VOLUME}" ]; do - if [ ! "$(synoacltool -get \"${DIRNAME}\"| grep \"group:${GROUP}:allow:r.x\")" ]; then + if [ ! "$(synoacltool -get ""${DIRNAME}"" | grep ""group:${GROUP}:allow:r.x"")" ]; then # Here we also need to make sure the admin can access data via File Station - if [ "$(synoacltool -get \"${DIRNAME}\"| grep \"Linux mode\")" ]; then + if [ "$(synoacltool -get ""${DIRNAME}"" | grep -i 'Linux mode')" ]; then synoacltool -add "${DIRNAME}" "group:administrators:allow:rwxpdDaARWc--:fd--" fi # Add the new group permissions @@ -212,26 +212,12 @@ preinst () call_func "validate_preinst" call_func "service_preinst" - # Check volume exists - if [ -n "${SHARE_PATH}" ]; then - if [ ! -d "${SHARE_VOLUME}" ]; then - echo "ERROR: Volume ${SHARE_VOLUME} does not exist." | $TEE 1>&2 - exit 1 - fi - fi - exit 0 } postinst () { log_step "postinst" - call_func "save_wizard_variables" - # Restrict permissions to protect sensitive options - if [ -e "${INST_VARIABLES}" ]; then - chmod go-rwx ${INST_VARIABLES} - chown ${EFF_USER} ${INST_VARIABLES} - fi # Link for backward compatibility of binaries location $LN "${SYNOPKG_PKGDEST}" "/usr/local/${SYNOPKG_PKGNAME}" 2>&1 | install_log @@ -278,34 +264,58 @@ postinst () # Share management if [ -n "${SHARE_PATH}" ]; then - install_log "Configuring ${SHARE_PATH}" - # Create share if does not exist - # !"#$%&’()*+,/:;<=>?@[]nˆ`{} | - if ! synoshare --get "${SHARE_NAME}" &> /dev/null; then - synoshare --add "${SHARE_NAME}" "${SHARE_DESC}" "${SHARE_PATH}" "" "" "" 1 0 2>&1 | install_log + # Create share if it does not exist + # invalid characters: !"#$%&’()*+,/:;<=>?@[]nˆ`{} | + if ! synoshare --get "${SHARE_NAME}" > /dev/null 2>&1; then + SHARE_PATH=${SYNOPKG_PKGDEST_VOL}/${SHARE_NAME} + install_log "Create share SHARE_NAME=${SHARE_NAME}, SHARE_PATH=${SHARE_PATH}" + # mandatory arguments: + # name desc path na rw ro browseable adv_privilege + # na, rw and ro are list of user(s) and/or group(s), separated by comma + synoshare --add "${SHARE_NAME}" "Share created for package ${SYNOPKG_PKGNAME}" "${SHARE_PATH}" "" "" "" 1 0 2>&1 | install_log + else + install_log "Share already exists SHARE_NAME=${SHARE_NAME}, SHARE_PATH=${SHARE_PATH}" fi - # Add user permission if no GROUP is set in UI + # Add user permission if no GROUP is set in service-setup # GROUP permission will be added in set_syno_permissions if [ -z "$GROUP" ] && [ -n "${EFF_USER}" ]; then - synoshare --setuser "${SHARE_NAME}" RW + "${EFF_USER}" 2>&1 | install_log + # check whether user is already added to RW users + _synoshare_parameter="--getmap" + if synoshare --getmap "${SHARE_NAME}" | grep "ACL.*\[yes\]" > /dev/null 2>&1; then + _synoshare_parameter="--list_acl" + fi + if synoshare ${_synoshare_parameter} "${SHARE_NAME}" | grep "RW list" | grep -o "\[.*\]" | sed 's/[\[,]/ /g' | sed 's/\]/ /g' | grep -q " ${EFF_USER} " > /dev/null 2>&1; then + install_log "User has already RW access to share: SHARE_NAME=${SHARE_NAME}, EFF_USER=${EFF_USER}" + else + install_log "Set user for share: SHARE_NAME=${SHARE_NAME}, EFF_USER=${EFF_USER}" + synoshare --setuser "${SHARE_NAME}" RW + "${EFF_USER}" 2>&1 | install_log + fi fi synoshare --build 2>&1 | install_log - $MKDIR "${SHARE_PATH}" - # Permissions for folder, up to volume if [ -n "$GROUP" ]; then + install_log "Set group for share: SHARE_PATH=${SHARE_PATH}, GROUP=${GROUP}" set_syno_permissions "${SHARE_PATH}" "${GROUP}" 2>&1 | install_log fi fi $MKDIR "${SYNOPKG_PKGVAR}" 2>&1 | install_log + call_func "save_wizard_variables" + # Restrict permissions to protect sensitive options + if [ -e "${INST_VARIABLES}" ]; then + chmod go-rwx ${INST_VARIABLES} + chown ${EFF_USER} ${INST_VARIABLES} + fi + call_func "service_postinst" + call_func "service_create_links" $CP "${INST_LOG_TEMP}" "${INST_LOG}" 2>&1 | install_log + if [ -n "${LOG_FILE}" ]; then echo "Installation log: ${INST_LOG}" >> ${LOG_FILE} fi @@ -330,6 +340,7 @@ preuninst () fi call_func "service_preuninst" + exit 0 } @@ -354,6 +365,7 @@ postuninst () if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then $RM "${INST_VARIABLES}" 2>&1 | install_log fi + exit 0 } @@ -393,5 +405,6 @@ postupgrade () # Make sure we also have the logging for this step $CP "${INST_LOG_TEMP}" "${INST_LOG}" 2>&1 | install_log + exit 0 } diff --git a/mk/spksrc.service.installer.dsm6 b/mk/spksrc.service.installer.dsm6 index e33f0cc0d62..d6a53eddf27 100644 --- a/mk/spksrc.service.installer.dsm6 +++ b/mk/spksrc.service.installer.dsm6 @@ -68,7 +68,7 @@ fi # Load (wizard) variables stored by postinst -call_func "load_variables_from_file" install_log ${INST_VARIABLES} +load_variables_from_file ${INST_VARIABLES} # init variables either from ${INST_VARIABLES}, from package or from wizard call_func "initialize_variables" @@ -148,9 +148,9 @@ set_syno_permissions () # Ensure directory resides in /volumeX before setting GROUP permissions if [ "$(echo ${VOLUME} | cut -c2-7)" = "volume" ]; then # Set read/write permissions for GROUP for folder and subfolders - if [ ! "$(synoacltool -get ""${DIRNAME}"" | grep ""group:${GROUP}:allow:rwxpdDaARWcC-:fd--"")" ]; then + if [ ! "$(synoacltool -get ${DIRNAME} | grep ""group:${GROUP}:allow:rwxpdDaARWcC-:fd--"")" ]; then # First Unix permissions, but only if it's in Linux mode - if [ "$(synoacltool -get ""${DIRNAME}"" | grep -i 'Linux mode')" ]; then + if [ "$(synoacltool -get ${DIRNAME} | grep -i 'Linux mode')" ]; then set_unix_permissions "${DIRNAME}" # If it is linux mode (due to old package) we need to add "administrators"-group, # otherwise the folder is not accessible from File Station anymore! @@ -224,26 +224,12 @@ preinst () call_func "validate_preinst" call_func "service_preinst" install_log - # Check volume exists - if [ -n "${SHARE_PATH}" ]; then - if [ ! -d "${SHARE_VOLUME}" ]; then - echo "ERROR: Volume ${SHARE_VOLUME} does not exist." | $TEE 1>&2 - exit 1 - fi - fi - exit 0 } postinst () { log_step "postinst" - call_func "save_wizard_variables" install_log - # Restrict permissions to protect sensitive options - if [ -e "${INST_VARIABLES}" ]; then - chmod go-rwx ${INST_VARIABLES} - chown ${EFF_USER} ${INST_VARIABLES} - fi # Link for backward compatibility of binaries location $LN "${SYNOPKG_PKGDEST}" "/usr/local/${SYNOPKG_PKGNAME}" 2>&1 | install_log @@ -273,33 +259,60 @@ postinst () synogroup --rebuild all 2>&1 | install_log fi - # Share management + # Share management (can be removed when SERVICE_WIZARD_SHARE is not used anymore) if [ -n "${SHARE_PATH}" ]; then - install_log "Configuring ${SHARE_PATH}" - # Create share if does not exist - # !"#$%&’()*+,/:;<=>?@[]nˆ`{} | - if ! synoshare --get "${SHARE_NAME}" &> /dev/null; then - synoshare --add "${SHARE_NAME}" "${SHARE_DESC}" "${SHARE_PATH}" "" "" "" 1 0 2>&1 | install_log - fi - - # Add user permission if no GROUP is set in UI - # GROUP permission will be added in set_syno_permissions - if [ -z "$GROUP" ] && [ -n "${EFF_USER}" ]; then - synoshare --setuser "${SHARE_NAME}" RW + "${EFF_USER}" 2>&1 | install_log - fi - synoshare --build 2>&1 | install_log + if [ "${SHARE_WORKER}" != "0" ]; then + install_log "Shared folder [${SHARE_PATH}] will be created by DSM." + else + # Create share if it does not exist + # invalid characters: !"#$%&’()*+,/:;<=>?@[]nˆ`{} | + if ! synoshare --get "${SHARE_NAME}" > /dev/null 2>&1; then + SHARE_PATH=${SYNOPKG_PKGDEST_VOL}/${SHARE_NAME} + install_log "Create share SHARE_NAME=${SHARE_NAME}, SHARE_PATH=${SHARE_PATH}" + # mandatory arguments: + # name desc path na rw ro browseable adv_privilege + # na, rw and ro are list of user(s) and/or group(s), separated by comma + synoshare --add "${SHARE_NAME}" "Share created for package ${SYNOPKG_PKGNAME}" "${SHARE_PATH}" "" "" "" 1 0 2>&1 | install_log + else + install_log "Share already exists SHARE_NAME=${SHARE_NAME}, SHARE_PATH=${SHARE_PATH}" + fi - $MKDIR "${SHARE_PATH}" + # Add user permission if no GROUP is set in service-setup + # GROUP permission will be added in set_syno_permissions + if [ -z "$GROUP" ] && [ -n "${EFF_USER}" ]; then + # check whether user is already added to RW users + _synoshare_parameter="--getmap" + if synoshare --getmap "${SHARE_NAME}" | grep "ACL.*\[yes\]" > /dev/null 2>&1; then + _synoshare_parameter="--list_acl" + fi + if synoshare ${_synoshare_parameter} "${SHARE_NAME}" | grep "RW list" | grep -o "\[.*\]" | sed 's/[\[,]/ /g' | sed 's/\]/ /g' | grep -q " ${EFF_USER} " > /dev/null 2>&1; then + install_log "User has already RW access to share: SHARE_NAME=${SHARE_NAME}, EFF_USER=${EFF_USER}" + else + install_log "Set user for share: SHARE_NAME=${SHARE_NAME}, EFF_USER=${EFF_USER}" + synoshare --setuser "${SHARE_NAME}" RW + "${EFF_USER}" 2>&1 | install_log + fi + fi + synoshare --build 2>&1 | install_log - # Permissions for folder, up to volume - if [ -n "$GROUP" ]; then - set_syno_permissions "${SHARE_PATH}" "${GROUP}" 2>&1 | install_log + # Permissions for folder, up to volume + if [ -n "$GROUP" ]; then + install_log "Set group for share: SHARE_PATH=${SHARE_PATH}, GROUP=${GROUP}" + set_syno_permissions "${SHARE_PATH}" "${GROUP}" 2>&1 | install_log + fi fi fi $MKDIR "${SYNOPKG_PKGVAR}" 2>&1 | install_log + call_func "save_wizard_variables" install_log + # Restrict permissions to protect sensitive options + if [ -e "${INST_VARIABLES}" ]; then + chmod go-rwx ${INST_VARIABLES} + chown ${EFF_USER} ${INST_VARIABLES} + fi + call_func "service_postinst" install_log + call_func "service_clean_tmpdir" install_log if [ -n "${LOG_FILE}" ]; then @@ -317,6 +330,7 @@ preuninst () log_step "preuninst" call_func "validate_preuninst" call_func "service_preuninst" install_log + exit 0 } @@ -340,6 +354,7 @@ postuninst () if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then $RM "${INST_VARIABLES}" 2>&1 | install_log fi + exit 0 } @@ -358,6 +373,7 @@ preupgrade () # Beware of /. outside the quotes # Needed to copy all files including hidden ones $CP "${SYNOPKG_PKGVAR}"/. "$TMP_DIR" 2>&1 | install_log + exit 0 } diff --git a/mk/spksrc.service.installer.dsm7 b/mk/spksrc.service.installer.dsm7 index 0a17d4bd86e..13a2d1310c7 100644 --- a/mk/spksrc.service.installer.dsm7 +++ b/mk/spksrc.service.installer.dsm7 @@ -69,7 +69,7 @@ fi # Load (wizard) variables stored by postinst -call_func "load_variables_from_file" install_log ${INST_VARIABLES} +load_variables_from_file ${INST_VARIABLES} # init variables either from ${INST_VARIABLES}, from package or from wizard call_func "initialize_variables" @@ -148,14 +148,6 @@ preinst () call_func "validate_preinst" call_func "service_preinst" install_log - # Check volume exists - if [ -n "${SHARE_PATH}" ]; then - if [ ! -d "${SHARE_VOLUME}" ]; then - echo "ERROR: Volume ${SHARE_VOLUME} does not exist." | $TEE 1>&2 - exit 1 - fi - fi - exit 0 } @@ -182,6 +174,7 @@ preuninst () log_step "preuninst" call_func "validate_preuninst" call_func "service_preuninst" install_log + exit 0 } @@ -200,10 +193,12 @@ postuninst () find ${SYNOPKG_PKGVAR} -mindepth 1 -delete -print | install_log fi - if [ "$(ls -A /var/packages/${SYNOPKG_PKGNAME}/etc)" != "" ]; then - find /var/packages/${SYNOPKG_PKGNAME}/etc -mindepth 1 -delete -print | install_log + _etc_path=$(realpath /var/packages/${SYNOPKG_PKGNAME}/etc) + if [ "$(ls -A ${_etc_path})" != "" ]; then + find ${_etc_path} -mindepth 1 -delete -print | install_log fi fi + exit 0 } @@ -229,6 +224,7 @@ preupgrade () call_func "service_preupgrade" install_log call_func "service_save" install_log + exit 0 } diff --git a/mk/spksrc.service.installer.functions b/mk/spksrc.service.installer.functions index d252322f175..4e7890b118f 100644 --- a/mk/spksrc.service.installer.functions +++ b/mk/spksrc.service.installer.functions @@ -1,4 +1,3 @@ - ### common installer functions and variables for synocommunity generic service installer # # functions are common for all DSM versions @@ -46,13 +45,25 @@ initialize_variables () GROUP_DESC="SynoCommunity Package Group" fi - # Extract share volume and share name from download location if provided + # Extract share volume and share name from share path when provided, and not already defined if [ -n "${SHARE_PATH}" ]; then - if [ -n "${wizard_volume}" ]; then - SHARE_PATH="${wizard_volume}/${SHARE_PATH}" + install_log "Evaluate full path for SHARE_NAME [${SHARE_NAME}] and SHARE_PATH [${SHARE_PATH}]" + # migrate SHARE_PATH that holds the share name only to full share path + # this is required for installers without resource worker for file share (SRM 1, DSM 5, DSM 6 old packages) + if [ "$(echo ${SHARE_PATH} | grep ^/)" != "${SHARE_PATH}" ]; then + SHARE_NAME=${SHARE_PATH} + if synoshare --get "${SHARE_NAME}" &> /dev/null; then + SHARE_PATH=$(synoshare --get "${SHARE_NAME}" | awk 'NR==4' | cut -d] -f1 | cut -d[ -f2) + install_log "Path of existing share [${SHARE_NAME}] is [${SHARE_PATH}]" + else + install_log "SHARE_NAME is not an existing share [${SHARE_PATH}]." + fi + else + install_log "SHARE_PATH is absolute path [${SHARE_PATH}]." + fi + if [ -z "${SHARE_NAME}" ]; then + SHARE_NAME=$(echo $(abspath ${SHARE_PATH}) | awk -F/ '{print $3}') fi - SHARE_VOLUME=$(echo "${SHARE_PATH}" | awk -F/ '{print "/"$2}') - SHARE_NAME=$(echo "${SHARE_PATH}" | awk -F/ '{print $3}') fi } @@ -104,14 +115,18 @@ install_python_wheels () # function to read and export variables from a text file # empty lines and lines starting with # are ignored # we cannot 'source' the file to load the variables, when values have special characters like <, >, ... +# already defined variables are not taken from the file (e.g. variables from wizard) load_variables_from_file () { if [ -n "$1" -a -r "$1" ]; then while read -r _line; do if [ "$(echo ${_line} | grep -v ^[/s]*#)" != "" ]; then - _key="$(echo ${_line} | cut --fields=1 --delimiter==)" - _value="$(echo ${_line} | cut --fields=2- --delimiter==)" - export "${_key}=${_value}" + _key=${_line%%=*} + _value=${_line#*=} + _existing_value=$(eval echo "\$${_key}") + if [ -z "${_existing_value}" ]; then + export "${_key}=${_value}" + fi fi done < "$1" fi @@ -120,7 +135,7 @@ load_variables_from_file () save_wizard_variables () { - if [ -e "${INST_VARIABLES}" ]; then + if [ -e "${INST_VARIABLES}" -a -n "${GROUP}${SHARE_PATH}${SHARE_NAME}" ]; then $RM "${INST_VARIABLES}" fi if [ -n "${GROUP}" ]; then @@ -129,4 +144,7 @@ save_wizard_variables () if [ -n "${SHARE_PATH}" ]; then echo "SHARE_PATH=${SHARE_PATH}" >> ${INST_VARIABLES} fi + if [ -n "${SHARE_NAME}" ]; then + echo "SHARE_NAME=${SHARE_NAME}" >> ${INST_VARIABLES} + fi } diff --git a/mk/spksrc.service.mk b/mk/spksrc.service.mk index cc7fb8eaef8..b9b1c5ed818 100644 --- a/mk/spksrc.service.mk +++ b/mk/spksrc.service.mk @@ -4,10 +4,10 @@ # scripts/start-stop-status # scripts/service-setup # conf/privilege if SERVICE_USER or DSM7 -# conf/SPK_NAME.sc if SERVICE_PORT and DSM<7 +# conf/$(SPK_NAME).sc if SERVICE_PORT and DSM<7 # conf/resource if SERVICE_CERT or DSM7 -# app/SPK_NAME.sc if SERVICE_PORT and DSM7 -# app/config if DSM_UI_DIR (may be overwritten by DSM_UI_CONFIG) +# app/$(SPK_NAME).sc if SERVICE_PORT and DSM7 +# app/config if SPK_ICON and SERVICE_PORT but not NO_SERVICE_SHORTCUT (may be overwritten by DSM_UI_CONFIG) # # Targets are executed in the following order: # service_msg_target @@ -17,23 +17,26 @@ # # Variables: # SERVICE_SETUP service-setup script file for generic installer +# SERVICE_PORT for generation of service port firewall config file (*.sc) and for dsm-ui config file # FWPORTS (optional) custom firewall port/rules file -# SERVICE_PORT service port firewall config file (*.sc) and dsm-ui config file -# SERVICE_PORT_PROTOCOL service port protocol for dsm-ui config file, default = "http" -# SERVICE_PORT_ALL_USERS service port access for all users for dsm-ui config file, default = "true" +# DSM_UI_DIR defaults to app. May be defined different for custom DSM UI integration +# # SERVICE_CERT (optional) configure DSM certificate management for this service name from the firewall config file (*.sc) # SERVICE_CERT_RELOAD (optional) package-relative path to a script for reloading the service after certificate changes -# SERVICE_TYPE service type for dsm-ui config file, default = "url" -# SERVICE_WIZARD_GROUP (optional) use name of wizard-variable to define the GROUP -# SERVICE_WIZARD_SHARE (optional) use name of wizard-varible to define SHARE_PATH (uses DSM data share worker for DSM 7) -# USE_DATA_SHARE_WORKER (optional) use DSM data share worker for SERVICE_WIZARD_SHARE and DSM 6 too +# +# SERVICE_WIZARD_SHARENAME (optional) this is the name of wizard-varible to define folder name of SHARE_PATH (uses DSM data share worker for DSM 6 and DSM 7) +# SERVICE_WIZARD_SHARE (deprecated) name of wizard-varible to define SHARE_PATH +# USE_DATA_SHARE_WORKER (deprecated, optional) use DSM data share worker for SERVICE_WIZARD_SHARE for DSM 6 too +# SERVICE_WIZARD_GROUP (not supported anymore) name of wizard-variable to define the GROUP +# SERVICE_WIZARD_GROUP is not supported anymore (not compatible with DSM 7 and DSM 6 using resource worker) +# # SERVICE_USER (optional) runtime user account for generic service support. # "auto" is the only value supported with DSM 7 and defines sc-${SPK_NAME} as service user. # SPK_GROUP (optional) defines the group to use in privilege resource file # SYSTEM_GROUP (optional) defines an additional group to join in privilege resource file # STARTABLE default = yes, must be "no" for packages that do not create a service (command line tools) # SERVICE_COMMAND service command, to be used with generic service support -# SERVICE_EXE (deprecated) service command, implemented with busybox start-stop-daemon +# SERVICE_EXE (not supported anymore) service command, implemented with busybox start-stop-daemon # SPK_COMMANDS (optional) list of "folder/command" to create links for in folder /usr/local # SPK_USR_LOCAL_LINKS (optional) list of "folder:command" to create links for in folder /usr/local # with 'command' in relative folder @@ -41,8 +44,17 @@ # folder at intallation and runtime. # SSS_SCRIPT (optional) custom script file for service start/stop/status when the generic # installer generated script (SERVICE_SETUP) is not usable. -# NO_SERVICE_SHORTCUT (optional) do not create an app icon in the DSM desktop # INSTALLER_SCRIPT (deprecated) installer script file before introduction of generic installer +# +# Variables for the dsm-ui config file (app/config) the definition for the app icon in the DSM UI and its properties. +# The app icon (i.e. the app/config file) is created, when SERVICE_PORT or DSM_UI_CONF is defined +# and can be disabled by definition of NO_SERVICE_SHORTCUT +# DSM_UI_CONF (optional) custom app/config file (required for web services without SERVICE_PORT) +# NO_SERVICE_SHORTCUT (optional) do not create an app icon (app/config) +# SERVICE_PORT_PROTOCOL service port protocol for dsm-ui config file, default = "http" +# SERVICE_PORT_ALL_USERS service port access for all users for dsm-ui config file, default = "true" +# SERVICE_TYPE service type for dsm-ui config file, default = "url" +# SERVICE_DESC service desc for dsm-ui config file, i.e. the tooltip on the app icon (default = $(DESCRIPTION)) # ifeq ($(strip $(PRE_SERVICE_TARGET)),) @@ -83,26 +95,32 @@ service_msg_target: pre_service_target: service_msg_target ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) -# always use SPK_USER on DSM >= 7, not only when SERVICE_USER is defined -SPK_USER = $(SPK_NAME) +# always use SPK_USER on DSM >= 7 +SERVICE_USER = auto ifneq ($(strip $(SERVICE_WIZARD_SHARE)),) # always use data share worker on DSM >= 7 USE_DATA_SHARE_WORKER = yes endif -else +endif + +# we need the service user to define access rights for the shared folder +ifneq ($(SERVICE_WIZARD_SHARENAME),) +ifeq ($(SERVICE_USER),) +SERVICE_USER = auto +endif +endif + # SERVICE_USER=auto uses SPK_NAME ifeq ($(SERVICE_USER),auto) SPK_USER = $(SPK_NAME) else ifneq ($(strip $(SERVICE_USER)),) -$(warning Only 'SERVICE_USER=auto' is compatible with DSM7) -SPK_USER = $(SERVICE_USER) -endif +$(error Only 'SERVICE_USER=auto' is supported since DSM7) endif # Recommend explicit STARTABLE=no -ifeq ($(strip $(SSS_SCRIPT) $(SERVICE_COMMAND) $(SERVICE_EXE) $(STARTABLE)),) +ifeq ($(strip $(SSS_SCRIPT) $(SERVICE_COMMAND) $(STARTABLE)),) ifeq ($(strip $(SPK_COMMANDS) $(SPK_USR_LOCAL_LINKS)),) -$(error Set STARTABLE=no or provide either SERVICE_COMMAND, SERVICE_EXE, SSS_SCRIPT, SPK_COMMANDS or SPK_USR_LOCAL_LINKS) +$(error Set STARTABLE=no or provide either SERVICE_COMMAND, SSS_SCRIPT, SPK_COMMANDS or SPK_USR_LOCAL_LINKS) endif endif @@ -123,26 +141,35 @@ $(DSM_SCRIPTS_DIR)/service-setup: @echo 'fi' >> $@ @echo '' >> $@ ifneq ($(strip $(SERVICE_USER)),) -ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) - @echo USER=\"sc-$(SPK_USER)\" >> $@ - @echo EFF_USER=\"sc-$(SPK_USER)\" >> $@ -else - @echo "# Base service USER to run background process prefixed according to DSM" >> $@ @echo USER=\"$(SPK_USER)\" >> $@ - @echo "PRIV_PREFIX=sc-" >> $@ - @echo "SYNOUSER_PREFIX=svc-" >> $@ - @echo 'if [ -n "$${SYNOPKG_DSM_VERSION_MAJOR}" ] && [ "$${SYNOPKG_DSM_VERSION_MAJOR}" -lt 6 ]; then EFF_USER="$${SYNOUSER_PREFIX}$${USER}"; else EFF_USER="$${PRIV_PREFIX}$${USER}"; fi' >> $@ -endif + @echo EFF_USER=\"sc-$(SPK_USER)\" >> $@ @echo '' >> $@ endif ifneq ($(strip $(SERVICE_WIZARD_GROUP)),) - @echo "# Group name from UI if provided" >> $@ - @echo 'if [ -n "$${$(SERVICE_WIZARD_GROUP)}" ]; then GROUP="$${$(SERVICE_WIZARD_GROUP)}"; fi' >> $@ - @echo '' >> $@ + $(error "SERVICE_WIZARD_GROUP is not supported anymore.") endif ifneq ($(strip $(SERVICE_WIZARD_SHARE)),) @echo "# DSM shared folder location from UI if provided" >> $@ - @echo 'if [ -n "$${$(SERVICE_WIZARD_SHARE)}" ]; then SHARE_PATH="$${$(SERVICE_WIZARD_SHARE)}"; fi' >> $@ + @echo 'if [ -n "$${$(SERVICE_WIZARD_SHARE)}" ]; then SHARE_PATH="$${$(SERVICE_WIZARD_SHARE)}"; SHARE_WORKER=0; fi' >> $@ +else +ifneq ($(strip $(SERVICE_WIZARD_SHARENAME)),) + @echo "# DSM name of shared folder from UI if provided" >> $@ + @echo 'if [ -n "$${$(SERVICE_WIZARD_SHARENAME)}" ]; then' >> $@ +ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) + @echo ' SHARE_PATH=$$(realpath "/var/packages/$${SYNOPKG_PKGNAME}/shares/$${$(SERVICE_WIZARD_SHARENAME)}" 2> /dev/null)' >> $@ + @echo ' install_log "SHARE_PATH from share [$${SHARE_PATH}], variable [$(SERVICE_WIZARD_SHARENAME)=$${$(SERVICE_WIZARD_SHARENAME)}]"' >> $@ +else + @echo ' if synoshare --get "$${$(SERVICE_WIZARD_SHARENAME)}" &> /dev/null; then ' >> $@ + @echo ' SHARE_PATH=$$(synoshare --get "$${$(SERVICE_WIZARD_SHARENAME)}" | awk 'NR==4' | cut -d] -f1 | cut -d[ -f2)' >> $@ + @echo ' install_log "SHARE_PATH from share [$${SHARE_PATH}], variable [$(SERVICE_WIZARD_SHARENAME)=$${$(SERVICE_WIZARD_SHARENAME)}]"' >> $@ + @echo ' else' >> $@ + @echo ' SHARE_PATH="$${$(SERVICE_WIZARD_SHARENAME)}"' >> $@ + @echo ' install_log "SHARE_PATH [$${$(SERVICE_WIZARD_SHARENAME)}] does not yet exist."' >> $@ + @echo ' fi' >> $@ +endif + @echo ' SHARE_NAME="$${$(SERVICE_WIZARD_SHARENAME)}"' >> $@ + @echo 'fi' >> $@ +endif @echo '' >> $@ endif ifneq ($(strip $(SERVICE_PORT)),) @@ -174,16 +201,12 @@ ifneq ($(strip $(SERVICE_COMMAND)),) @echo '' >> $@ endif ifneq ($(strip $(SERVICE_EXE)),) -ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) - @echo "${RED}ERROR: SERVICE_EXE (start-stop-daemon) is unsupported in DSM7${NC}" + @echo "${RED}ERROR: SERVICE_EXE (start-stop-daemon) is not supported anymore${NC}" @echo "${GREEN}Please migrate to SERVICE_COMMAND=${NC}" @exit 1 endif - @echo "# Service command to execute with start-stop-daemon" >> $@ - @echo 'SERVICE_EXE="$(SERVICE_EXE)"' >> $@ ifneq ($(strip $(SERVICE_OPTIONS)),) @echo 'SERVICE_OPTIONS="$(SERVICE_OPTIONS)"' >> $@ -endif @echo '' >> $@ endif ifeq ($(strip $(USE_ALTERNATE_TMPDIR)),1) @@ -237,6 +260,14 @@ ifeq ($(strip $(USE_DATA_SHARE_WORKER)),yes) @jq --arg share "{{${SERVICE_WIZARD_SHARE}}}" --arg user sc-${SPK_USER} \ '."data-share" = {"shares": [{"name": $$share, "permission":{"rw":[$$user]}} ] }' $@ | sponge $@ endif +else +ifneq ($(strip $(SERVICE_WIZARD_SHARENAME)),) +# e.g. SERVICE_WIZARD_SHARENAME=wizard_sharename, for DSM 6 and DSM 7 +ifeq ($(call version_ge, ${TCVERSION}, 6.1),1) + @jq --arg share "{{${SERVICE_WIZARD_SHARENAME}}}" --arg user sc-${SPK_USER} \ + '."data-share" = {"shares": [{"name": $$share, "permission":{"rw":[$$user]}} ] }' $@ | sponge $@ +endif +endif endif ifneq ($(strip $(SERVICE_CERT)),) ifeq ($(call version_lt, ${TCVERSION}, 7.0),1) @@ -299,9 +330,6 @@ DSM_SCRIPT_FILES += start-stop-status ifeq ($(STARTABLE),no) $(DSM_SCRIPTS_DIR)/start-stop-status: $(SPKSRC_MK)spksrc.service.non-startable @$(dsm_script_copy) -else ifneq ($(strip $(SERVICE_EXE)),) -$(DSM_SCRIPTS_DIR)/start-stop-status: $(SPKSRC_MK)spksrc.service.start-stop-daemon - @$(dsm_script_copy) else $(DSM_SCRIPTS_DIR)/start-stop-status: $(SPKSRC_MK)spksrc.service.start-stop-status @$(dsm_script_copy) @@ -340,15 +368,9 @@ endif # DSM <= 6 and SERVICE_USER defined else ifneq ($(strip $(SERVICE_USER)),) -ifeq ($(strip $(SERVICE_EXE)),) $(DSM_CONF_DIR)/privilege: $(SPKSRC_MK)spksrc.service.privilege-installasroot @$(dsm_resource_copy) @$(MSG) "(privilege) spksrc.service.privilege-installasroot" -else -$(DSM_CONF_DIR)/privilege: $(SPKSRC_MK)spksrc.service.privilege-startasroot - @$(dsm_resource_copy) - @$(MSG) "(privilege) spksrc.service.privilege-startasroot" -endif ifneq ($(strip $(SYSTEM_GROUP)),) # options: http, system @jq '."join-groupname" = "$(SYSTEM_GROUP)"' $@ | sponge $@ @@ -401,10 +423,26 @@ $(STAGING_DIR)/$(DSM_UI_DIR)/$(SPK_NAME).sc: $(filter %.sc,$(FWPORTS)) SERVICE_FILES += $(STAGING_DIR)/$(DSM_UI_DIR)/$(SPK_NAME).sc endif -# Generate DSM UI configuration +# Generate DSM UI configuration (app/config) +# prerequisites: +# - SPK_ICON is required and NO_SERVICE_SHORTCUT is not defined +# - if DSM_UI_CONFIG is defined, it is used as config file +# - else SERVICE_PORT is defined: +# - the config file is generated with the SERVICE_PORT and the following variables +# - SERVICE_DESC +# - SERVICE_URL +# - SERVICE_PORT_PROTOCOL +# - SERVICE_PORT_ALL_USERS +# - SERVICE_TYPE +# default values are documentent at the top of this file ifneq ($(strip $(SPK_ICON)),) -ifneq ($(strip $(SERVICE_PORT)),) ifeq ($(strip $(NO_SERVICE_SHORTCUT)),) +ifneq ($(wildcard $(DSM_UI_CONFIG)),) +$(STAGING_DIR)/$(DSM_UI_DIR)/config: + $(create_target_dir) + cat $(DSM_UI_CONFIG) > $@ +SERVICE_FILES += $(STAGING_DIR)/$(DSM_UI_DIR)/config +else ifneq ($(strip $(SERVICE_PORT)),) # Set some defaults ifeq ($(strip $(SERVICE_URL)),) SERVICE_URL=/ @@ -418,15 +456,13 @@ endif ifeq ($(strip $(SERVICE_TYPE)),) SERVICE_TYPE=url endif - -DESC=$(shell echo ${DESCRIPTION} | sed -e 's/\\//g' -e 's/"/\\"/g') +ifeq ($(strip $(SERVICE_DESC)),) +SERVICE_DESC=$(shell echo ${DESCRIPTION} | sed -e 's/\\//g' -e 's/"/\\"/g') +endif $(STAGING_DIR)/$(DSM_UI_DIR)/config: $(create_target_dir) -ifneq ($(wildcard $(DSM_UI_CONFIG)),) - cat $(DSM_UI_CONFIG) > $@ -else @echo '{}' | jq --arg name "${DISPLAY_NAME}" \ - --arg desc "${DESC}" \ + --arg desc "${SERVICE_DESC}" \ --arg id "com.synocommunity.packages.${SPK_NAME}" \ --arg icon "images/${SPK_NAME}-{0}.png" \ --arg prot "${SERVICE_PORT_PROTOCOL}" \ @@ -435,7 +471,6 @@ else --arg type "${SERVICE_TYPE}" \ --argjson allUsers ${SERVICE_PORT_ALL_USERS} \ '{".url":{($$id):{"title":$$name, "desc":$$desc, "icon":$$icon, "type":$$type, "protocol":$$prot, "port":$$port, "url":$$url, "allUsers":$$allUsers, "grantPrivilege":"all", "advanceGrantPrivilege":true}}}' > $@ -endif SERVICE_FILES += $(STAGING_DIR)/$(DSM_UI_DIR)/config endif endif diff --git a/mk/spksrc.service.privilege-startasroot b/mk/spksrc.service.privilege-startasroot deleted file mode 100644 index ec7285735be..00000000000 --- a/mk/spksrc.service.privilege-startasroot +++ /dev/null @@ -1,34 +0,0 @@ -{ - "defaults":{ - "run-as": "package" - }, - "username": "USER", - "ctrl-script": [{ - "action": "preinst", - "run-as": "root" - }, { - "action": "postinst", - "run-as": "root" - }, { - "action": "preuninst", - "run-as": "root" - }, { - "action": "postuninst", - "run-as": "root" - }, { - "action": "preupgrade", - "run-as": "root" - }, { - "action": "postupgrade", - "run-as": "root" - }, { - "action": "start", - "run-as": "root" - }, { - "action": "stop", - "run-as": "root" - }, { - "action": "status", - "run-as": "root" - }] -} diff --git a/mk/spksrc.service.start-stop-daemon b/mk/spksrc.service.start-stop-daemon deleted file mode 100644 index c9d9bb2e161..00000000000 --- a/mk/spksrc.service.start-stop-daemon +++ /dev/null @@ -1,125 +0,0 @@ -#!/bin/sh - -# Default display name -DNAME="${SYNOPKG_PKGNAME}" - -if [ "$SYNOPKG_DSM_VERSION_MAJOR" -lt 7 ]; then - # define SYNOPKG_PKGVAR for forward compatibility - SYNOPKG_PKGVAR="${SYNOPKG_PKGDEST}/var" -fi - -# Source package specific variable and functions -SVC_SETUP=$(dirname $0)"/service-setup" -if [ -r "${SVC_SETUP}" ]; then - . "${SVC_SETUP}" -fi - - -# Invoke shell function if available -call_func () -{ - FUNC=$1 - if type "${FUNC}" 2>/dev/null | grep -q 'function' 2>/dev/null; then - echo "Begin ${FUNC}" >> ${LOG_FILE} - eval ${FUNC} >> ${LOG_FILE} - echo "End ${FUNC}" >> ${LOG_FILE} - fi -} - - -start_daemon () -{ - if [ -z "${SVC_QUIET}" ]; then - if [ -z "${SVC_KEEP_LOG}" ]; then - date > ${LOG_FILE} - else - date >> ${LOG_FILE} - fi - fi - call_func "service_prestart" - if [ -z "${SVC_QUIET}" ]; then - echo "Starting ${DNAME} command ${SERVICE_EXE} ${SERVICE_OPTIONS} " >> ${LOG_FILE} - fi - if [ -n "${SERVICE_EXE}" ]; then - if [ -n "${SERVICE_OPTIONS}" ]; then - start-stop-daemon -o -S -b -p ${PID_FILE} -m -c ${EFF_USER} -k 002 -x "${SERVICE_EXE}" -- ${SERVICE_OPTIONS} - else - start-stop-daemon -o -S -b -p ${PID_FILE} -m -c ${EFF_USER} -k 002 -x "${SERVICE_EXE}" - fi - fi -} - -stop_daemon () -{ - start-stop-daemon -o -K -u ${EFF_USER} -x "${SERVICE_EXE}" - wait_for_status 1 20 || start-stop-daemon -K -s 9 -q -x "${SERVICE_EXE}" - call_func "service_poststop" -} - -daemon_status () -{ - start-stop-daemon -K -q -t -u ${EFF_USER} -x "${SERVICE_EXE}" - [ $? -eq 0 ] || return 1 -} - -wait_for_status () -{ - timeout=$2 - # default value: 20 seconds - counter=${timeout:=20} - while [ ${counter} -gt 0 ]; do - daemon_status - [ $? -eq $1 ] && return - let counter=counter-1 - sleep 1 - done - return 1 -} - - -case $1 in - start) - if daemon_status; then - echo "${DNAME} is already running" >> ${LOG_FILE} - exit 0 - else - echo "Starting ${DNAME} ..." >> ${LOG_FILE} - start_daemon - exit $? - fi - ;; - stop) - if daemon_status; then - echo "Stopping ${DNAME} ..." >> ${LOG_FILE} - stop_daemon - exit $? - else - echo "${DNAME} is not running" >> ${LOG_FILE} - exit 0 - fi - ;; - status) - if daemon_status; then - echo "${DNAME} is running" - exit 0 - else - echo "${DNAME} is not running" - exit 3 - fi - ;; - log) - # log output for DSM < 6 - if [ -n "${LOG_FILE}" -a -r "${LOG_FILE}" ]; then - # Shorten long logs to last 100 lines - TEMP_LOG_FILE="${SYNOPKG_PKGVAR}/${SYNOPKG_PKGNAME}_temp.log" - # Clear any previous log - echo "Full log: ${LOG_FILE}" > "${TEMP_LOG_FILE}" - tail -n100 "${LOG_FILE}" >> "${TEMP_LOG_FILE}" - echo "${TEMP_LOG_FILE}" - fi - exit 0 - ;; - *) - exit 1 - ;; -esac diff --git a/spk/adminer/Makefile b/spk/adminer/Makefile index 969a4cf69dc..9a7190b7fdb 100644 --- a/spk/adminer/Makefile +++ b/spk/adminer/Makefile @@ -14,7 +14,7 @@ DISPLAY_NAME = Adminer CHANGELOG = "1. Update to v4.8.1
This package depends on Apache 2.4 and PHP 7.4 (except for DSM < 6)." HOMEPAGE = https://www.adminer.org -LICENSE = Apache License 2.0 or GPL 2 +LICENSE = Apache 2.0 or GPLv2 include ../../mk/spksrc.common.mk ## @@ -35,8 +35,7 @@ START_DEP_SERVICES = apache-web INSTUNINST_RESTART_SERVICES = apache-web SERVICE_SETUP = src/service-setup.sh -# we need a nop sss script to avoid creation of service control. -SSS_SCRIPT = src/dsm-control.sh +STARTABLE = no WIZARDS_DIR = src/wizard/ POST_STRIP_TARGET = adminer_extra_install @@ -48,6 +47,5 @@ include ../../mk/spksrc.spk.mk .PHONY: adminer_extra_install adminer_extra_install: - install -m 755 -d $(STAGING_DIR)/var $(STAGING_DIR)/app $(STAGING_DIR)/web - install -m 644 src/app/config $(STAGING_DIR)/app/config + install -m 755 -d $(STAGING_DIR)/web install -m 644 src/dot-htaccess-apache$(APACHE_VERSION) $(STAGING_DIR)/web/.htaccess diff --git a/spk/adminer/src/dsm-control.sh b/spk/adminer/src/dsm-control.sh deleted file mode 100644 index 33c02538635..00000000000 --- a/spk/adminer/src/dsm-control.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -case $1 in - start) - exit 0 - ;; - stop) - exit 0 - ;; - status) - exit 0 - ;; - log) - exit 1 - ;; - *) - exit 1 - ;; -esac diff --git a/spk/aria2/Makefile b/spk/aria2/Makefile index 7f347f513b8..ddcec2ed099 100644 --- a/spk/aria2/Makefile +++ b/spk/aria2/Makefile @@ -29,7 +29,6 @@ WIZARDS_DIR = src/wizard # 'auto' reserved value grabs SPK_NAME SERVICE_USER = auto -SERVICE_WIZARD_GROUP = wizard_group SERVICE_WIZARD_SHARE = wizard_download_dir SERVICE_SETUP = src/service-setup.sh diff --git a/spk/aria2/src/service-setup.sh b/spk/aria2/src/service-setup.sh index 3e959980e69..57daa819060 100644 --- a/spk/aria2/src/service-setup.sh +++ b/spk/aria2/src/service-setup.sh @@ -24,7 +24,6 @@ service_preinst () exit 1 } fi - set_syno_permissions "${wizard_download_dir}" "${wizard_group}" fi } diff --git a/spk/aria2/src/wizard/install_uifile b/spk/aria2/src/wizard/install_uifile index 2a953f93966..3b5a2ae8bc6 100644 --- a/spk/aria2/src/wizard/install_uifile +++ b/spk/aria2/src/wizard/install_uifile @@ -3,24 +3,6 @@ "step_title": "Aria2 Configuration", "invalid_next_disabled": true, "items": [ - { - "type": "textfield", - "desc": "Synology DSM Settings", - "subitems": [ - { - "key": "wizard_group", - "desc": "DSM group", - "defaultValue": "sc-aria2", - "validator": { - "allowBlank": false, - "regex": { - "expr": "/^[^<>:*/?\"]*$/", - "errorText": "Not allowed character in group name" - } - } - } - ] - }, { "type": "textfield", "desc": "Aria2 Settings", diff --git a/spk/aria2/src/wizard/install_uifile_chs b/spk/aria2/src/wizard/install_uifile_chs index effc3e10e76..1bfb614d636 100644 --- a/spk/aria2/src/wizard/install_uifile_chs +++ b/spk/aria2/src/wizard/install_uifile_chs @@ -3,24 +3,6 @@ "step_title": "Aria2 配置", "invalid_next_disabled": true, "items": [ - { - "type": "textfield", - "desc": "群晖 DSM 设置", - "subitems": [ - { - "key": "wizard_group", - "desc": "用户组", - "defaultValue": "sc-aria2", - "validator": { - "allowBlank": false, - "regex": { - "expr": "/^[^<>:*/?\"]*$/", - "errorText": "用户组不应含有^[^<>:*/?\"]*等特殊字符" - } - } - } - ] - }, { "type": "textfield", "desc": "Aria2 设置", diff --git a/spk/cops/Makefile b/spk/cops/Makefile index eeaa6c806d2..664011a197d 100644 --- a/spk/cops/Makefile +++ b/spk/cops/Makefile @@ -4,7 +4,7 @@ SPK_REV = 7 SPK_ICON = src/cops.png DSM_UI_DIR = app -DEPENDS = cross/$(SPK_NAME) +DEPENDS = cross/cops MAINTAINER = Diaoul DESCRIPTION = Calibre OPDS and HTML PHP Server : light alternative to Calibre content server / Calibre2OPDS. @@ -14,14 +14,13 @@ DISPLAY_NAME = COPS CHANGELOG = "1. Update to 1.4.2
2. Upgrade PHP 7.4
3. Add .htaccess migration support" include ../../mk/spksrc.common.mk -include ../../mk/spksrc.directories.mk SPK_DEPENDS=WebStation:PHP7.4:Apache2.4 SYSTEM_GROUP = http -HOMEPAGE = https://blog.slucas.fr/en/oss/calibre-opds-php-server -LICENSE = GPL +HOMEPAGE = https://blog.slucas.fr/en/oss/calibre-opds-php-server +LICENSE = GPLv2 REQUIRED_MIN_DSM = 6.0 @@ -39,13 +38,9 @@ POST_STRIP_TARGET = cops_extra_install # Pure PHP package, make sure ARCH is not defined override ARCH= -ICON_DIR = $(STAGING_DIR)/$(DSM_UI_DIR)/images - include ../../mk/spksrc.spk.mk .PHONY: cops_extra_install cops_extra_install: - install -m 755 -d $(STAGING_DIR)/app - install -m 644 src/app/config $(STAGING_DIR)/app/config + @$(MSG) Install default config file install -m 666 src/config_local.php.synology $(STAGING_DIR)/config_local.php.synology - diff --git a/spk/cops/src/service-setup.sh b/spk/cops/src/service-setup.sh index 0e9a8a9d534..e948c155942 100644 --- a/spk/cops/src/service-setup.sh +++ b/spk/cops/src/service-setup.sh @@ -1,4 +1,3 @@ -#!/bin/sh # Package PACKAGE_NAME="com.synocommunity.packages.${SYNOPKG_PKGNAME}" @@ -33,24 +32,24 @@ validate_preinst () service_postinst () { - if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then - + if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then + # Install the web interface cp -pR "${SYNOPKG_PKGDEST}/share/${SYNOPKG_PKGNAME}" "${WEB_DIR}" - + # Configure open_basedir echo -e "[PATH=${WEB_DIR}/${SYNOPKG_PKGNAME}]\nopen_basedir = Null" > "${PHP_CONFIG_LOCATION}/${PACKAGE_NAME}.ini" - fi + fi if [ "${SYNOPKG_PKG_STATUS}" == "INSTALL" ]; then # Create a default configuration file if [ ! -f "${CFG_FILE}" ]; then - cp "${DEFAULT_CFG_FILE}" "${CFG_FILE}" - url_rewriting=$([ "${wizard_use_url_rewriting}" == "true" ] && echo "1" || echo "0") - sed -i -e "s|@calibre_dir@|${wizard_calibre_dir:=/volume1/calibre/}|g" ${CFG_FILE} - sed -i -e "s|@cops_title@|${wizard_cops_title:=COPS}|g" ${CFG_FILE} - sed -i -e "s|@use_url_rewriting@|${url_rewriting:=0}|g" ${CFG_FILE} - chmod ga+w "${CFG_FILE}" + cp "${DEFAULT_CFG_FILE}" "${CFG_FILE}" + url_rewriting=$([ "${wizard_use_url_rewriting}" == "true" ] && echo "1" || echo "0") + sed -i -e "s|@calibre_dir@|${wizard_calibre_dir:=/volume1/calibre/}|g" ${CFG_FILE} + sed -i -e "s|@cops_title@|${wizard_cops_title:=COPS}|g" ${CFG_FILE} + sed -i -e "s|@use_url_rewriting@|${url_rewriting:=0}|g" ${CFG_FILE} + chmod ga+w "${CFG_FILE}" fi if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then @@ -58,7 +57,7 @@ service_postinst () # Set permissions on directory structure (DSM 5+) set_syno_permissions "${wizard_calibre_dir}" "${GROUP}" # Set permissions on metadata.db - if [ ! "`synoacltool -get "${wizard_calibre_dir}/metadata.db"| grep "group:${GROUP}:allow:rwxpdDaARWc."`" ]; then + if [ ! "$(synoacltool -get ""${wizard_calibre_dir}/metadata.db""| grep group:${GROUP}:allow:rwxpdDaARWc.)" ]; then synoacltool -add "${wizard_calibre_dir}/metadata.db" "group:${GROUP}:allow:rwxpdDaARWc:----" > /dev/null 2>&1 fi fi @@ -68,15 +67,14 @@ service_postinst () service_postuninst () { if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then - # Remove link - rm -f "${SYNOPKG_PKGDEST}" + # Remove link + rm -f "${SYNOPKG_PKGDEST}" - # Remove open_basedir configuration - rm -f "${PHP_CONFIG_LOCATION}/${PACKAGE_NAME}.ini" + # Remove open_basedir configuration + rm -f "${PHP_CONFIG_LOCATION}/${PACKAGE_NAME}.ini" - # Remove the web interface - rm -fr "${WEB_DIR:?}/${SYNOPKG_PKGNAME}" - + # Remove the web interface + rm -fr "${WEB_DIR:?}/${SYNOPKG_PKGNAME}" fi } @@ -90,20 +88,20 @@ service_save () # Save .htaccess file mv -v "${SECURITY_SETTINGS_FILE}" "${TMP_DIR}/${SYNOPKG_PKGNAME}/" if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then - mv -v "${PHP_CONFIG_LOCATION}/${PACKAGE_NAME}.ini" "${TMP_DIR}/${SYNOPKG_PKGNAME}/" + mv -v "${PHP_CONFIG_LOCATION}/${PACKAGE_NAME}.ini" "${TMP_DIR}/${SYNOPKG_PKGNAME}/" fi } service_restore () { - # Restore some stuff - rm -f "${CFG_FILE}" - # Restore cops configuration file - mv -v "${TMP_DIR}/${SYNOPKG_PKGNAME}/${CFG_FILE_NAME}" "${CFG_FILE}" - # Restore .htaccess file - mv -v "${TMP_DIR}/${SYNOPKG_PKGNAME}/${SECURITY_SETTINGS_FILE_NAME}" "${SECURITY_SETTINGS_FILE}" - if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then + # Restore some stuff + rm -f "${CFG_FILE}" + # Restore cops configuration file + mv -v "${TMP_DIR}/${SYNOPKG_PKGNAME}/${CFG_FILE_NAME}" "${CFG_FILE}" + # Restore .htaccess file + mv -v "${TMP_DIR}/${SYNOPKG_PKGNAME}/${SECURITY_SETTINGS_FILE_NAME}" "${SECURITY_SETTINGS_FILE}" + if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then mv "${TMP_DIR}/${SYNOPKG_PKGNAME}/${PACKAGE_NAME}.ini" "${PHP_CONFIG_LOCATION}/" - fi - rm -d "${TMP_DIR}/${SYNOPKG_PKGNAME}" "${TMP_DIR}" + fi + rm -d "${TMP_DIR}/${SYNOPKG_PKGNAME}" "${TMP_DIR}" } diff --git a/spk/demoservice/Makefile b/spk/demoservice/Makefile index 8af51983ab6..41922ed966b 100644 --- a/spk/demoservice/Makefile +++ b/spk/demoservice/Makefile @@ -6,46 +6,55 @@ SPK_ICON = src/demoservice.png override ARCH= MAINTAINER = ymartin59 -DESCRIPTION = Demonstration package to show installer script capabilities when requiring non-root user for background service -DISPLAY_NAME = DemoService -CHANGELOG = "1. Update with new installer logs
2. Update for DSM7" +DESCRIPTION = Demonstration package to show installer script capabilities when requiring non-root user for background service and show configuration/creation of shared folder for package user. +DISPLAY_NAME = Demo Service +CHANGELOG = "1. Use redesigned shared folder handling.
2. Fix service command to work on SRM and DSM 5.
3. Use Pyhton 3 when available in path." LICENSE = GPLv2 WIZARDS_DIR = src/wizard/ -# 'auto' reserved value grabs SPK_NAME +# 'auto' reserved value grabs SPK_NAME (only auto is supported) SERVICE_USER = auto -SERVICE_WIZARD_GROUP = wizard_group - -include ../../mk/spksrc.common.mk -ifneq ($(call version_ge, ${TCVERSION}, 7.0),1) -# SERVICE_WIZARD_SHARE is not supported for DSM7 yet -SERVICE_WIZARD_SHARE = wizard_download_dir -endif - SERVICE_SETUP = src/service-setup.sh +# The spksrc framework does not parse the service-setup.sh file for valid SERVICE_COMMAND +# so we have to tell it, that the package provides a startable service. STARTABLE = yes +# New with redesigned shared folder handling: +# The wizard must take a name for the shared folder to use or create +# Entering the full path for shared folders is not supported anymore. +SERVICE_WIZARD_SHARENAME = wizard_shared_folder_name + # Service configuration SERVICE_PORT = 8888 -SERVICE_PORT_TITLE = DemoService (HTTP) +SERVICE_PORT_TITLE = $(DISPLAY_NAME) (HTTP) +SERVICE_DESC = Demo Service Package -# Admin link +# Admin link (optional) +# Create a link in the package center for this package. +# Just for demonstration since an app icon in DSM is created with the same target. ADMIN_PORT = $(SERVICE_PORT) PRE_COPY_TARGET = demoservice_pre_copy +POST_STRIP_TARGET = demoservice_extra_install include ../../mk/spksrc.spk.mk -.PHONY: demoservice_install +.PHONY: demoservice_pre_copy # Replace standard copy/install targets, no sources, no content demoservice_pre_copy: - @$(MSG) Create README and dummy file - rm -fr $(STAGING_DIR) - mkdir $(STAGING_DIR) - mkdir --parents $(STAGING_INSTALL_PREFIX_VAR) - echo "Test file for $(INSTALL_PREFIX_VAR)" > $(STAGING_INSTALL_PREFIX_VAR)/README - # create dummy file (avoid empty target folder for DSM 7 packages) + @$(MSG) Create README and dummy files + mkdir -p $(STAGING_INSTALL_PREFIX_VAR) + echo "Test file for /var/packages/$(SPK_NAME)/var/README" > $(STAGING_INSTALL_PREFIX_VAR)/README + echo "INSTALL_PREFIX_VAR = $(INSTALL_PREFIX_VAR)" >> $(STAGING_INSTALL_PREFIX_VAR)/README + echo "STAGING_INSTALL_PREFIX = $(STAGING_INSTALL_PREFIX)" >> $(STAGING_INSTALL_PREFIX_VAR)/README + @$(MSG) Create dummy file to avoid empty target folder for DSM 7 packages mkdir -p $(STAGING_INSTALL_PREFIX) echo "dummy file (to avoid empty package)" > $(STAGING_INSTALL_PREFIX)/dummy + +.PHONY: demoservice_extra_install +demoservice_extra_install: + @$(MSG) Install service script + @install -d -m 777 $(STAGING_DIR)/bin/ + @install -m 755 src/start.sh $(STAGING_DIR)/bin/ diff --git a/spk/demoservice/src/service-setup.sh b/spk/demoservice/src/service-setup.sh index 9bc5002049d..097afa08543 100644 --- a/spk/demoservice/src/service-setup.sh +++ b/spk/demoservice/src/service-setup.sh @@ -2,19 +2,12 @@ # Package specific behaviors # Sourced script by generic installer and start-stop-status scripts -SERVER_MODULE="SimpleHTTPServer" -PYTHON_VERSION=$(python --version 2>&1) -PYTHON_MAJOR_VERSION=$(echo ${PYTHON_VERSION} | cut -d ' ' -f2 | cut -d . -f1) +# pass variables to service script by env +export PID_FILE=${PID_FILE} +export SERVICE_PORT=${SERVICE_PORT} -if [ "${PYTHON_MAJOR_VERSION}" == "3" ]; then -SERVER_MODULE="http.server" -fi - - -SERVICE_COMMAND="python -m ${SERVER_MODULE} ${SERVICE_PORT}" +SERVICE_COMMAND="${SYNOPKG_PKGDEST}/bin/start.sh" SVC_CWD="${SYNOPKG_PKGVAR}" -SVC_BACKGROUND=y -SVC_WRITE_PID=y # These functions are for demonstration purpose of DSM sequence call @@ -27,6 +20,11 @@ validate_preinst () # use install_log to write to installer log file. install_log "validate_preinst ${SYNOPKG_PKG_STATUS}" + # variables not available in preinst + install_log "Variables:" + install_log "SHARE_PATH=${SHARE_PATH}" + install_log "SHARE_NAME=${SHARE_NAME}" + # writing to stdout in dsm7 shows "installation error" without exit 1 (this looks like an error of DSM7 beta) #echo "preinst validation notification" @@ -37,6 +35,11 @@ validate_preuninst () { # use install_log to write to installer log file. install_log "validate_preuninst ${SYNOPKG_PKG_STATUS}" + + # variables not available in preinst + install_log "Variables:" + install_log "SHARE_PATH=${SHARE_PATH}" + install_log "SHARE_NAME=${SHARE_NAME}" # writing to stdout in dsm7 shows "installation error" without exit 1 (this looks like an error of DSM7 beta) #echo "preuninst validation notification" @@ -49,6 +52,10 @@ validate_preupgrade () # use install_log to write to installer log file. install_log "validate_preupgrade ${SYNOPKG_PKG_STATUS}" + install_log "Variables:" + install_log "SHARE_PATH=${SHARE_PATH}" + install_log "SHARE_NAME=${SHARE_NAME}" + # writing to stdout in dsm7 shows "installation error" without exit 1 (this looks like an error of DSM7 beta) #echo "preupgrade validation notification" @@ -60,11 +67,9 @@ service_preinst () # use echo to write to the installer log file. echo "service_preinst ${SYNOPKG_PKG_STATUS}" - echo "PYTHON_VERSION: ${PYTHON_VERSION}" - echo "PYTHON_MAJOR_VERSION: ${PYTHON_MAJOR_VERSION}" - echo "SERVER_MODULE: ${SERVER_MODULE}" - echo "SERVICE_COMMAND: ${SERVICE_COMMAND}" - echo "SYNOPKG_PKGVAR: ${SYNOPKG_PKGVAR}" + echo "Variables:" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" } service_postinst () @@ -72,13 +77,21 @@ service_postinst () # use echo to write to the installer log file. echo "service_postinst ${SYNOPKG_PKG_STATUS}" - ln -sf ${INST_LOG} ${SYNOPKG_PKGVAR}/installer.log + echo "Variables:" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" + + ln -sf ${INST_LOG} ${SYNOPKG_PKGVAR}/${SYNOPKG_PKGNAME}-installer.log } service_preuninst () { # use echo to write to the installer log file. echo "service_preuninst ${SYNOPKG_PKG_STATUS}" + + echo "Variables:" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" } service_postuninst () @@ -91,18 +104,41 @@ service_preupgrade () { # use echo to write to the installer log file. echo "service_preupgrade ${SYNOPKG_PKG_STATUS}" + + echo "Variables:" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" } service_postupgrade () { # use echo to write to the installer log file. echo "service_postupgrade ${SYNOPKG_PKG_STATUS}" + + echo "Variables:" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" } +# REMARKS: +# installer variables are not available in the context of service start/stop +# The regular solution is to use configuration files for services + service_prestart () { # use echo to write to the service log file. echo "service_prestart: Before service start" + + # This code shows how to load and use the function 'load_variables_from_file' + # defined in the script/functions file + INST_FUNCTIONS=$(dirname $0)"/functions" + if [ -r "${INST_FUNCTIONS}" ]; then + . "${INST_FUNCTIONS}" + load_variables_from_file ${INST_VARIABLES} + echo "Variables read from ${INST_VARIABLES}" + echo "SHARE_PATH=${SHARE_PATH}" + echo "SHARE_NAME=${SHARE_NAME}" + fi } service_poststop () diff --git a/spk/demoservice/src/start.sh b/spk/demoservice/src/start.sh new file mode 100644 index 00000000000..22a5498d101 --- /dev/null +++ b/spk/demoservice/src/start.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# we need a single file to start the service and create the pid-file +# the combination of +# - SVC_BACKGROUND=y +# - SVC_WRITE_PID=y +# does not work in DSM 5 when SERVICE_COMMAND is a commend with parameters +# On DSM 5 /bin/sh is ash and not bash and '/bin/sh -c "command parameter" &' will create a new process for "command parameter" +# finally we have two processes in the background, but are not able to retrieve the PID of "command parameter" +# + +if [ -z "${PID_FILE}" ]; then +echo "ERROR: PID_FILE is not defined. This script must be run in the context of DSM service command." +exit 1 +fi + + +PYTHON=python +if [ -n "$(which python3 2> /dev/null)" ]; then +PYTHON=python3 +fi + +PYTHON_VERSION=$(${PYTHON} --version 2>&1) +PYTHON_MAJOR_VERSION=$(echo ${PYTHON_VERSION} | cut -d ' ' -f2 | cut -d . -f1) + +SERVER_MODULE="SimpleHTTPServer" +if [ "${PYTHON_MAJOR_VERSION}" == "3" ]; then +SERVER_MODULE="http.server" +fi + +echo "current user: $(id)" +echo "python version: ${PYTHON_VERSION}" +echo "service command: ${PYTHON} -m ${SERVER_MODULE} ${SERVICE_PORT}" + +${PYTHON} -m ${SERVER_MODULE} ${SERVICE_PORT} & +echo "$!" > ${PID_FILE} diff --git a/spk/demoservice/src/wizard/install_uifile b/spk/demoservice/src/wizard/install_uifile index 83cc56f0f13..2e59d8e36e3 100644 --- a/spk/demoservice/src/wizard/install_uifile +++ b/spk/demoservice/src/wizard/install_uifile @@ -1,44 +1,31 @@ [ { - "step_title": "Example configuration for demoservice", + "step_title": "Demo Configuration", "items": [ { "type": "textfield", - "desc": "Download configuration", + "desc": "Please specify a shared folder for this package. This share is created at installation when it does not already exist.", "subitems": [ { - "key": "wizard_download_dir", - "desc": "Download location", - "defaultValue": "/volume1/downloads", + "key": "wizard_shared_folder_name", + "desc": "Shared Folder", + "defaultValue": "demo-share", "validator": { "allowBlank": false, "regex": { - "expr": "/^\\\/volume[0-9]{1,2}\\\/[^<>: */?\"]*/", - "errorText": "Path should begin with /volume?/ where ? is volume number (1-99)" - } - } - }, - { - "key": "wizard_group", - "desc": "DSM group", - "defaultValue": "sc-download", - "validator": { - "allowBlank": false, - "regex": { - "expr": "/^[^<>:*/?\"]*$/", - "errorText": "Not allowed character in group name" - } + "expr": "/^[\\w _-]+$/", + "errorText": "Subdirectories are not supported." } } } ] - } - ] - }, - { - "step_title": "Attention! DSM Permissions", - "items": [ - { - "desc": "Permissions are managed with the group 'sc-download' in DSM.
The group 'users' is no longer used as of DSM 6.
Package user (= demoservice) will not appear on most UI settings.
Including the following:
- Application privilege's permission viewer
- FPT's chroot user selector
- File Stations's
- Change owner
- Shared Links Manager -> Enable secure sharing

The only exceptions are:
- Control Panel > Shared Folder > Edit > Permission > System internal user
- ACL editor
" + }, { + "desc": "" + }, { + "desc": "If you let the installer create the shared folder, it is created under the same volume as the package is installed.
If you want to use a different volume for the share, you must create the shared folder in DSM Control Panel before, and enter the name of the existing share in the field above." + }, { + "desc": "" + }, { + "desc": "This package runs as internal service user 'sc-demoservice' in DSM. The shared folder above is configured at installation time to be accessible by this user.

Please read Permission Management for details." } ] } diff --git a/spk/demoservice/src/wizard/install_uifile_fre b/spk/demoservice/src/wizard/install_uifile_fre index 91c482281fb..c2fa9494b26 100644 --- a/spk/demoservice/src/wizard/install_uifile_fre +++ b/spk/demoservice/src/wizard/install_uifile_fre @@ -1,44 +1,31 @@ [ { - "step_title": "Exemple de configuration pour demoservice", + "step_title": "Configuration de démonstration", "items": [ { "type": "textfield", - "desc": "Configuration de téléchargement", + "desc": "Veuillez spécifier un dossier partagé pour ce package. Ce partage est créé à l'installation lorsqu'il n'existe pas déjà.", "subitems": [ { - "key": "wizard_download_dir", - "desc": "Répertoire cible", - "defaultValue": "/volume1/downloads", + "key": "wizard_shared_folder_name", + "desc": "Shared Folder", + "defaultValue": "demo-share", "validator": { "allowBlank": false, "regex": { - "expr": "/^\\\/volume[0-9]{1,2}\\\/[^<>: */?\"]*/", - "errorText": "Le chemin doit commencer par /volume?/ avec ? le numéro du volume (1-99)" - } - } - }, - { - "key": "wizard_group", - "desc": "Groupe DSM", - "defaultValue": "sc-download", - "validator": { - "allowBlank": false, - "regex": { - "expr": "/^[^<>:*/?\"]*$/", - "errorText": "Caractère non autorisé dans le nom de groupe" - } + "expr": "/^[\\w _-]+$/", + "errorText": "Les sous-répertoires ne sont pas pris en charge." } } } ] - } - ] - }, - { - "step_title": "Attention! DSM Permissions", - "items": [ - { - "desc": "Les autorisations sont gérées avec le groupe 'sc-download' dans DSM.
Le groupe 'utilisateurs' n'est plus utilisé à partir de DSM 6.
L'utilisateur du paquet (= demoservice) n'apparaîtra pas sur la plupart des paramètres d'interface utilisateur. Y compris ce qui suit:
- Afficheur d'autorisation de privilège d'application
- Sélecteur d'utilisateur chroot FPT
- File Stations's- Changer de propriétaire
- Shared Links Manager -> Activer le partage sécurisé

Les seules exceptions sont:
- Panneau de configuration> Dossier partagé> Edition> Autorisation> Utilisateur interne du système
- Éditeur ACL" + }, { + "desc": "" + }, { + "desc": "Si vous laissez le programme d'installation créer le dossier partagé, il est créé sous le même volume que celui où le package est installé.
Si vous souhaitez utiliser un volume différent pour le partage, vous devez auparavant créer le dossier partagé dans le panneau de configuration DSM et saisir le nom du partage existant dans le champ ci-dessus." + }, { + "desc": "" + }, { + "desc": "Ce package s'exécute en tant qu'utilisateur de service interne 'sc-demoservice' dans DSM. Le dossier partagé ci-dessus est configuré au moment de l'installation pour être accessible par cet utilisateur.

Veuillez lire Permission Management pour plus de détails." } ] } diff --git a/spk/demowebservice/Makefile b/spk/demowebservice/Makefile new file mode 100644 index 00000000000..b7825dff382 --- /dev/null +++ b/spk/demowebservice/Makefile @@ -0,0 +1,76 @@ +SPK_NAME = demowebservice +SPK_VERS = 1.0 +SPK_REV = 1 +SPK_ICON = src/demowebservice.png + +DEPENDS = + +override ARCH= + +MAINTAINER = hgy59 +DESCRIPTION = Demopackage to show how to create a web service \(web application\) +DISPLAY_NAME = Demo Web Service +CHANGELOG = "Initial package release" + +LICENSE = MIT + +include ../../mk/spksrc.common.mk +# use the latest php version +ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) +PHP_VERSION = 8.2 +endif + +# only for DSM 7 we have dedicated dependencies (must match the configuration in conf/resource) +ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) +SPK_DEPENDS = WebStation:PHP$(PHP_VERSION):Apache2.4 +else ifeq ($(call version_ge, ${TCVERSION}, 6.0),1) +# on DSM 6 the default web server and PHP version are used +SPK_DEPENDS = WebStation +endif + +WIZARDS_DIR = src/wizard/ +SERVICE_WIZARD_SHARENAME = wizard_shared_folder_name + +SYSTEM_GROUP = http + +DSM_UI_DIR = app +DSM_UI_CONFIG = src/app/config +ifeq ($(call version_ge, ${TCVERSION}, 7.0),1) +# webservice resource definition is for DSM 7 only +CONF_DIR = src/conf_php$(PHP_VERSION)/ +# The app/config file is not used on DSM 7 for web services, the app icon is created based on the resources in CONF_DIR only. +# With app/config on DSM 7 (sometimes) an error occurred: System error. Unable to perform this operation. Please try again later. +# Disable the creation of app/config file: +NO_SERVICE_SHORTCUT = y +# create firewall rules, since we add a port based "Web Portal" +SERVICE_PORT = 8889 +endif + +# apache-web dependency is not used: +# on DSM 7 the settings are ignored as dependency is defined in conf/resource +# on DSM 6 the package runs under the active web server (apache or nginx) +#INSTALL_DEP_SERVICES = apache-web +#START_DEP_SERVICES = apache-web +#INSTUNINST_RESTART_SERVICES = apache-web + +SERVICE_SETUP = src/service-setup.sh +STARTABLE = no + +COPY_TARGET = demowebservice_install +POST_ICON_TARGET = demowebservice_post_icon + +include ../../mk/spksrc.spk.mk + +.PHONY: demowebservice_install +demowebservice_install: + @$(MSG) Install the web application + @install -d -m 755 $(STAGING_DIR)/web/$(SPK_NAME)/ + @install -m 755 src/web/index.php $(STAGING_DIR)/web/$(SPK_NAME)/ + +.PHONY: demowebservice_post_icon +demowebservice_post_icon: + @$(MSG) Add some package icons to the web application + @install -d -m 755 $(STAGING_DIR)/web/$(SPK_NAME)/images + @for image_size in 16 32; do \ + install -m 755 $(STAGING_DIR)/app/images/$(SPK_NAME)-$${image_size}.png $(STAGING_DIR)/web/$(SPK_NAME)/images/ ; \ + done diff --git a/spk/demowebservice/src/app/config b/spk/demowebservice/src/app/config new file mode 100644 index 00000000000..f960fd23408 --- /dev/null +++ b/spk/demowebservice/src/app/config @@ -0,0 +1,15 @@ +{ + ".url": { + "com.synocommunity.packages.demowebservice": { + "type": "url", + "title": "Demo Web Service", + "desc": "Web Service Demo Package (Tooltip)", + "icon": "images/demowebservice-{0}.png", + "protocol": "http", + "port": "80", + "url": "/demowebservice", + "allUsers": true, + "grantPrivilege": "local" + } + } +} diff --git a/spk/demowebservice/src/conf_php7.4/resource b/spk/demowebservice/src/conf_php7.4/resource new file mode 100644 index 00000000000..d382faf39fc --- /dev/null +++ b/spk/demowebservice/src/conf_php7.4/resource @@ -0,0 +1,44 @@ +{ + "data-share": { + "shares": [ + { + "name": "{{wizard_shared_folder_name}}", + "permission":{"rw":["sc-demowebservice"]} + } + ] + }, + "webservice": { + "services": [{ + "service": "demowebservice", + "display_name": "Demo Web Service", + "icon": "app/images/demowebservice-{0}.png", + "type": "apache_php", + "root": "demowebservice", + "backend": 2, + "php": { + "profile_name": "Web Service Demo Profile", + "profile_desc": "PHP 7.4 profile for Demo Web Service", + "backend": 8, + "extensions": [], + "user": "sc-demowebservice", + "group": "http" + } + }], + "portals": [ + { + "service": "demowebservice", + "type": "alias", + "name": "Demo Web Service", + "alias": "demowebservice", + "app": "com.synocommunity.packages.demowebservice" + } + ], + "pkg_dir_prepare": [{ + "source": "/var/packages/demowebservice/target/web/demowebservice", + "target": "demowebservice", + "mode": "0755", + "user": "sc-demowebservice", + "group": "http" + }] + } +} \ No newline at end of file diff --git a/spk/demowebservice/src/conf_php8.2/resource b/spk/demowebservice/src/conf_php8.2/resource new file mode 100644 index 00000000000..c50ef83b657 --- /dev/null +++ b/spk/demowebservice/src/conf_php8.2/resource @@ -0,0 +1,55 @@ +{ + "data-share": { + "shares": [ + { + "name": "{{wizard_shared_folder_name}}", + "permission":{"rw":["sc-demowebservice"]} + } + ] + }, + "webservice": { + "services": [ + { + "service": "demowebservice", + "display_name": "Demo Web Service", + "icon": "app/images/demowebservice-{0}.png", + "type": "apache_php", + "root": "demowebservice", + "backend": 2, + "php": { + "profile_name": "Web Service Demo Profile", + "profile_desc": "PHP 8.2 profile for Demo Web Service", + "backend": 11, + "extensions": [], + "user": "sc-demowebservice", + "group": "http" + } + } + ], + "portals": [ + { + "service": "demowebservice", + "type": "alias", + "name": "Demo Web Service (Alias)", + "alias": "demowebservice", + "app": "com.synocommunity.packages.demowebservice" + }, + { + "service": "demowebservice", + "type": "server", + "name": "Demo Web Service (Port)", + "http_port": [8889], + "app": "com.synocommunity.packages.demowebservice" + } + ], + "pkg_dir_prepare": [ + { + "source": "/var/packages/demowebservice/target/web/demowebservice", + "target": "demowebservice", + "mode": "0755", + "user": "sc-demowebservice", + "group": "http" + } + ] + } +} \ No newline at end of file diff --git a/spk/demowebservice/src/demowebservice.png b/spk/demowebservice/src/demowebservice.png new file mode 100644 index 00000000000..3053dc7835d Binary files /dev/null and b/spk/demowebservice/src/demowebservice.png differ diff --git a/spk/demowebservice/src/service-setup.sh b/spk/demowebservice/src/service-setup.sh new file mode 100644 index 00000000000..c672a600230 --- /dev/null +++ b/spk/demowebservice/src/service-setup.sh @@ -0,0 +1,42 @@ + +if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then +WEB_ROOT=/var/services/web +GROUP=http +else +WEB_ROOT=/var/services/web_packages +fi + +WEB_DIR=${WEB_ROOT}/${SYNOPKG_PKGNAME} + +service_postinst () +{ + echo "Install the web app (${WEB_DIR})" + + if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then + # Install the web interface + # only DSM 7+ installs the web service based on the "webservice" resource. + cp -rp "${SYNOPKG_PKGDEST}/web/${SYNOPKG_PKGNAME}" ${WEB_ROOT}/ + fi + + if [ -d "${WEB_DIR}" ]; then + if [ -n "${SHARE_NAME}" ]; then + sed -e "s|@@shared_folder_name@@|${SHARE_NAME}|g" \ + -e "s|@@shared_folder_fullname@@|${SHARE_PATH}|g" \ + -i ${WEB_DIR}/index.php + else + echo "ERROR: SHARE_PATH is not defined" + fi + else + echo "ERROR: ${WEB_DIR} does not exist" + fi +} + +service_postuninst () +{ + if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -lt 7 ]; then + if [ -d "${WEB_DIR}" ]; then + echo "Remove the web app (${WEB_DIR})" + rm -rf ${WEB_DIR} + fi + fi +} diff --git a/spk/demowebservice/src/web/index.php b/spk/demowebservice/src/web/index.php new file mode 100644 index 00000000000..1d1f8084af4 --- /dev/null +++ b/spk/demowebservice/src/web/index.php @@ -0,0 +1,233 @@ + + + + + + + + + + + + +Demo Web Service + + + + + + +

+ +

Demo Web Service

+

This is a demo web service package for synology DSM.

+

It demonstrates how to build a package to integrate with web server and PHP.

+

It also shows how to configure and use a shared folder.

+ +

The source code is located in the SynoCommunity respository under demowebservice.

+ +

List of server variables:

+

 $key_value) { print $key_name . " = " . $key_value . "
"; } ?>

+ +

on PHP less than 8.x phpinfo() does not support dark mode and we use light mode for all pages.


"; +} +?> + +
+ +
+ +
+ +
+

Shared Folder

+

Name of the shared folder is @@shared_folder_name@@.

+

Full path of the shared folder is @@shared_folder_fullname@@.

+ +

The following list of files and folders shows that the package has access to this folder.

+ +

Content of the shared folder:

+

ERROR: open_basedir restriction in effect. Path (".$path.") is not within the allowed path(s).

"; + echo "

open_basedir=".ini_get('open_basedir')."

"; + echo "

You have to add ".$path." to the php open_basedir to list the folder content.

"; + } + else + { + if (file_exists($path)) { + try { + print_folder($path); + } + catch (Exception $e) { + echo "

ERROR: ".$e->getMessage()."

"; + } + } + else { + echo "

The folder '".$path."' does not exist.

"; + } + } + + function add_list_element($dom, $parent, $fileinfo) + { + $info = $fileinfo->getFilename(); + if ( !$fileinfo->isDir() ) { + $info .= " size=[".$fileinfo->getSize()." bytes]"; + } + $info .= " access=["; + if ($fileinfo->isReadable()) { $info .= "r"; } else { $info .= "-"; } + if ($fileinfo->isWritable()) { $info .= "w"; } else { $info .= "-"; } + if ($fileinfo->isExecutable()) { $info .= "x"; } else { $info .= "-"; } + $info .= "]"; + $info .= " owner=[".$fileinfo->getOwner().":".$fileinfo->getGroup()."]" ; + + $li = $dom->createElement('li', $info); + $parent->appendChild($li); + } + + // print directory tree based on the accepted answer in: + // https://stackoverflow.com/questions/10779546/recursiveiteratoriterator-and-recursivedirectoryiterator-to-nested-html-lists + function print_folder($path) + { + $directoryIteratorFlags = FilesystemIterator::KEY_AS_PATHNAME|FilesystemIterator::CURRENT_AS_FILEINFO|FilesystemIterator::SKIP_DOTS; + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, $directoryIteratorFlags), RecursiveIteratorIterator::SELF_FIRST); + $dom = new DomDocument("1.0"); + $list = $dom->createElement("ul"); + $dom->appendChild($list); + $node = $list; + $depth = 0; + foreach ($objects as $name => $object) { + if ($objects->getDepth() == $depth) { + // the depth hasn't changed so just add another li + add_list_element($dom,$node,$object); + } + elseif ($objects->getDepth() > $depth) { + // the depth increased, the last li is a non-empty folder + $li = $node->lastChild; + $ul = $dom->createElement('ul'); + $li->appendChild($ul); + add_list_element($dom,$ul,$object); + $node = $ul; + } + else { + // the depth decreased, going up $difference directories + $difference = $depth - $objects->getDepth(); + for ($i = 0; $i < $difference; $difference--) { + $node = $node->parentNode->parentNode; + } + add_list_element($dom,$node,$object); + } + $depth = $objects->getDepth(); + } + echo $dom->saveHtml(); + } +?> +
+ + + + + + + diff --git a/spk/demowebservice/src/wizard/install_uifile b/spk/demowebservice/src/wizard/install_uifile new file mode 100644 index 00000000000..19a75f7a5a9 --- /dev/null +++ b/spk/demowebservice/src/wizard/install_uifile @@ -0,0 +1,45 @@ +[ + { + "step_title": "Demo Web Service Configuration", + "items": [ + { + "type": "textfield", + "desc": "Please specify a shared folder for this package. This share is created at installation when it does not already exist.", + "subitems": [ + { + "key": "wizard_shared_folder_name", + "desc": "Shared Folder", + "defaultValue": "demo-share", + "validator": { + "allowBlank": false, + "regex": { + "expr": "/^[\\w _-]+$/", + "errorText": "Subdirectories are not supported." + } + } + } + ] + }, + { + "desc": "" + }, + { + "desc": "This package runs as internal service user 'sc-demowebservice' in DSM. The shared folder above is configured at installation time to be accessible by this user.

Please read Permission Management for details." + } + ] + }, + { + "step_title": "Miscellaneous Remarks", + "items": [ + { + "desc": "On DSM 6
In Web Station you can use any web server (apache or nginx) and you must configure a PHP profile for this demo to work." + }, + { + "desc": "On DSM 7
This demowebservice will be accessible by path (http://<local ip>/demowebservice) or by port (http://<local ip>:8889) on your diskstation.

The port based \"Web Portal\" allows reverse proxy configuration for this demo. Alas configuration of a reverse proxy does not work by the package installer and you would have to manually create a reverse proxy for http://localhost:8889." + }, + { + "desc": "PHP open_basedir
If this demowebservice can not display the content of the shared folder, you might have configured a non empty open_basedir in the PHP profile. To solve this, you must add the path of the shared folder. On DSM 7 a specific PHP profile with an empty open_basedir is installed, but on other systems you might face this restriction depending on the PHP profile used." + } + ] + } +] \ No newline at end of file diff --git a/spk/owncloud/Makefile b/spk/owncloud/Makefile index e549077fe9b..d919f4b1991 100644 --- a/spk/owncloud/Makefile +++ b/spk/owncloud/Makefile @@ -4,7 +4,7 @@ SPK_REV = 11 SPK_ICON = src/owncloud.png DSM_UI_DIR = app -DEPENDS = cross/$(SPK_NAME) +DEPENDS = cross/owncloud SPK_DEPENDS = "WebStation:PHP7.4:Apache2.4" REQUIRED_MIN_DSM = 6.0 @@ -45,8 +45,7 @@ include ../../mk/spksrc.spk.mk .PHONY: owncloud_extra_install owncloud_extra_install: - install -m 755 -d $(STAGING_DIR)/app -d $(STAGING_DIR)/bin -d $(STAGING_DIR)/web - install -m 644 src/app/config $(STAGING_DIR)/app/config + install -m 755 -d $(STAGING_DIR)/bin -d $(STAGING_DIR)/web install -m 755 src/bin/owncloud-daemon $(STAGING_DIR)/bin/owncloud-daemon install -m 644 src/web/owncloud.conf $(STAGING_DIR)/web/owncloud.conf install -m 644 src/web/owncloud.json $(STAGING_DIR)/web/owncloud.json